From 8aac6060d36c5dca48c02988b654d4646b175e64 Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Mon, 4 May 2020 20:33:48 +0300 Subject: oal upd --- src/audio/AudioManager.cpp | 4 +- src/audio/AudioManager.h | 4 +- src/audio/DMAudio.cpp | 23 + src/audio/DMAudio.h | 2 + src/audio/miles/sampman_mss.cpp | 2257 -------------------------------------- src/audio/miles/sampman_mss.h | 339 ------ src/audio/oal/aldlist.cpp | 329 ++++++ src/audio/oal/aldlist.h | 49 + src/audio/oal/channel.cpp | 209 ++++ src/audio/oal/channel.h | 51 + src/audio/oal/oal_utils.cpp | 176 +++ src/audio/oal/oal_utils.h | 48 + src/audio/oal/stream.cpp | 118 ++ src/audio/oal/stream.h | 57 + src/audio/openal/samp_oal.cpp | 1404 ------------------------ src/audio/openal/samp_oal.h | 340 ------ src/audio/sampman.cpp | 7 - src/audio/sampman.h | 348 +++++- src/audio/sampman_miles.cpp | 2311 +++++++++++++++++++++++++++++++++++++++ src/audio/sampman_oal.cpp | 1372 +++++++++++++++++++++++ src/core/Game.cpp | 19 +- src/core/config.h | 3 +- src/skel/win/win.cpp | 3 +- 23 files changed, 5099 insertions(+), 4374 deletions(-) delete mode 100644 src/audio/miles/sampman_mss.cpp delete mode 100644 src/audio/miles/sampman_mss.h create mode 100644 src/audio/oal/aldlist.cpp create mode 100644 src/audio/oal/aldlist.h create mode 100644 src/audio/oal/channel.cpp create mode 100644 src/audio/oal/channel.h create mode 100644 src/audio/oal/oal_utils.cpp create mode 100644 src/audio/oal/oal_utils.h create mode 100644 src/audio/oal/stream.cpp create mode 100644 src/audio/oal/stream.h delete mode 100644 src/audio/openal/samp_oal.cpp delete mode 100644 src/audio/openal/samp_oal.h delete mode 100644 src/audio/sampman.cpp create mode 100644 src/audio/sampman_miles.cpp create mode 100644 src/audio/sampman_oal.cpp (limited to 'src') diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index 4f015915..72d1fe30 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -9361,7 +9361,7 @@ cAudioManager::ResetTimers(uint32 time) SampleManager.SetEffectsFadeVolume(0); SampleManager.SetMusicFadeVolume(0); MusicManager.ResetMusicAfterReload(); -#ifdef OPENAL +#ifdef AUDIO_OAL SampleManager.Service(); #endif } @@ -9419,7 +9419,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 9479d1cd..8fc13ed8 100644 --- a/src/audio/AudioManager.h +++ b/src/audio/AudioManager.h @@ -600,6 +600,8 @@ public: uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); }; -//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..8681f345 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, "OPEANAL SOFT") ) + return i; +#endif + } + + return -1; +} + int8 cDMAudio::GetCurrent3DProviderIndex(void) { diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index 42688fa6..6a94d57f 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -205,6 +205,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.cpp b/src/audio/miles/sampman_mss.cpp deleted file mode 100644 index f3a6ba80..00000000 --- a/src/audio/miles/sampman_mss.cpp +++ /dev/null @@ -1,2257 +0,0 @@ -#include -#include -#include - -#include - -#include "eax.h" -#include "eax-util.h" -#include "mss.h" - -#include "sampman_mss.h" -#include "AudioManager.h" -#include "MusicManager.h" -#include "Frontend.h" -#include "Timer.h" - - -#pragma comment( lib, "mss32.lib" ) - -cSampleManager SampleManager; -int32 BankStartOffset[MAX_SAMPLEBANKS]; -/////////////////////////////////////////////////////////////// - -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; - -uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; - -uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; - -/////////////////////////////////////////////////////////////// -struct tMP3Entry -{ - char aFilename[MAX_PATH]; - - uint32 nTrackLength; - uint32 nTrackStreamPos; - - tMP3Entry *pNext; - char *pLinkPath; -}; - -uint32 nNumMP3s; -tMP3Entry *_pMP3List; -char _mp3DirectoryPath[MAX_PATH]; -HSTREAM mp3Stream [MAX_MP3STREAMS]; -int8 nStreamPan [MAX_MP3STREAMS]; -int8 nStreamVolume[MAX_MP3STREAMS]; -uint32 _CurMP3Index; -int32 _CurMP3Pos; -bool _bIsMp3Active; - -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) -bool _bUseHDDAudio; -char _aHDDPath[MAX_PATH]; -#endif -/////////////////////////////////////////////////////////////// - - -bool _bSampmanInitialised = false; - -// -// Miscellaneous globals / defines - -// 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; - -S32 prevprovider=-1; -S32 curprovider=-1; -S32 usingEAX=0; -S32 usingEAX3=0; -HPROVIDER opened_provider=0; -H3DSAMPLE opened_samples[MAXCHANNELS] = {0}; -HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0}; -HDIGDRIVER DIG; -S32 speaker_type=0; - -U32 _maxSamples; -float _fPrevEaxRatioDestination; -bool _usingMilesFast2D; -float _fEffectsLevel; - - -struct -{ - HPROVIDER id; - char name[80]; -}providers[MAXPROVIDERS]; - -typedef struct provider_stuff -{ - char* name; - HPROVIDER id; -} provider_stuff; - - -static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2) -{ - return( _stricmp(s1->name,s2->name) ); -} - -static void -add_providers() -{ - provider_stuff pi[MAXPROVIDERS]; - U32 n,i,j; - - SampleManager.SetNum3DProvidersAvailable(0); - - HPROENUM next = HPROENUM_FIRST; - - n=0; - while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n MAXCHANNELS ) - _maxSamples = MAXCHANNELS; - - SampleManager.SetSpeakerConfig(speaker_type); - - //obtain a 3D sample handles - for ( U32 i = 0; i < _maxSamples; ++i ) - { - opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider); - if ( opened_samples[i] != NULL ) - AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f); - } - - return true; - } - } - - return false; -} - -void -cSampleManager::SetSpeakerConfig(int32 which) -{ - switch ( which ) - { - case 1: - speaker_type=AIL_3D_2_SPEAKER; - break; - - case 2: - speaker_type=AIL_3D_HEADPHONE; - break; - - case 3: - speaker_type=AIL_3D_4_SPEAKER; - break; - - default: - return; - break; - } - - if (opened_provider) - AIL_set_3D_speaker_type(opened_provider, speaker_type); -} - -uint32 -cSampleManager::GetMaximumSupportedChannels(void) -{ - if ( _maxSamples > MAXCHANNELS ) - return MAXCHANNELS; - - return _maxSamples; -} - -int8 -cSampleManager::GetCurrent3DProviderIndex(void) -{ - return curprovider; -} - -int8 -cSampleManager::SetCurrent3DProvider(uint8 nProvider) -{ - S32 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; -} - -static bool -_ResolveLink(char const *path, char *out) -{ - IShellLink* psl; - WIN32_FIND_DATA fd; - char filepath[MAX_PATH]; - - CoInitialize(NULL); - - if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) - { - IPersistFile *ppf; - - if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) - { - WCHAR wpath[MAX_PATH]; - - MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); - - if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) - { - /* Resolve the link */ - if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) - { - strcpy(filepath, path); - - if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) - { - OutputDebugString(fd.cFileName); - - strcpy(out, filepath); - // FIX: Release the objects. Taken from SA. -#ifdef FIX_BUGS - ppf->Release(); - psl->Release(); -#endif - return true; - } - } - } - - ppf->Release(); - } - psl->Release(); - } - - return false; -} - -static void -_FindMP3s(void) -{ - tMP3Entry *pList; - bool bShortcut; - bool bInitFirstEntry; - HANDLE hFind; - char path[MAX_PATH]; - char filepath[MAX_PATH*2]; - S32 total_ms; - WIN32_FIND_DATA fd; - - - if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 ) - { - GetLastError(); - return; - } - - OutputDebugString("Finding MP3s..."); - strcpy(path, _mp3DirectoryPath); - strcat(path, "\\MP3\\"); - - strcpy(_mp3DirectoryPath, path); - OutputDebugString(_mp3DirectoryPath); - - strcat(path, "*"); - - hFind = FindFirstFile(path, &fd); - - if ( hFind == INVALID_HANDLE_VALUE ) - { - GetLastError(); - return; - } - - strcpy(filepath, _mp3DirectoryPath); - strcat(filepath, fd.cFileName); - - int32 filepathlen = strlen(filepath); - - if ( filepathlen <= 0) - { - FindClose(hFind); - return; - } - - FILE *f = fopen("MP3\\MP3Report.txt", "w"); - - if ( f ) - { - fprintf(f, "MP3 Report File\n\n"); - fprintf(f, "\"%s\"", fd.cFileName); - } - - - if ( filepathlen > 4 ) - { - if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) - { - if ( _ResolveLink(filepath, filepath) ) - { - OutputDebugString("Resolving Link"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); - } - - bShortcut = true; - } - else - bShortcut = false; - } - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - OutputDebugString(fd.cFileName); - - _pMP3List = new tMP3Entry; - - if ( _pMP3List == NULL ) - { - FindClose(hFind); - - if ( f ) - fclose(f); - - return; - } - - nNumMP3s = 1; - - strcpy(_pMP3List->aFilename, fd.cFileName); - - _pMP3List->nTrackLength = total_ms; - - _pMP3List->pNext = NULL; - - pList = _pMP3List; - - if ( bShortcut ) - { - _pMP3List->pLinkPath = new char[MAX_PATH*2]; - strcpy(_pMP3List->pLinkPath, filepath); - } - else - { - _pMP3List->pLinkPath = NULL; - } - - if ( f ) fprintf(f, " - OK\n"); - - bInitFirstEntry = false; - } - else - { - strcat(filepath, " - NOT A VALID MP3"); - - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - - bInitFirstEntry = true; - } - - while ( true ) - { - if ( !FindNextFile(hFind, &fd) ) - break; - - if ( bInitFirstEntry ) - { - strcpy(filepath, _mp3DirectoryPath); - strcat(filepath, fd.cFileName); - - int32 filepathlen = strlen(filepath); - - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - - if ( filepathlen > 0 ) - { - if ( filepathlen > 4 ) - { - if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) - { - if ( _ResolveLink(filepath, filepath) ) - { - OutputDebugString("Resolving Link"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); - } - - bShortcut = true; - } - else - { - bShortcut = false; - - if ( filepathlen > MAX_PATH ) - { - if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath); - - continue; - } - } - } - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - OutputDebugString(fd.cFileName); - - _pMP3List = new tMP3Entry; - - if ( _pMP3List == NULL) - break; - - nNumMP3s = 1; - - strcpy(_pMP3List->aFilename, fd.cFileName); - - _pMP3List->nTrackLength = total_ms; - _pMP3List->pNext = NULL; - - if ( bShortcut ) - { - _pMP3List->pLinkPath = new char [MAX_PATH*2]; - strcpy(_pMP3List->pLinkPath, filepath); - } - else - { - _pMP3List->pLinkPath = NULL; - } - - pList = _pMP3List; - - if ( f ) fprintf(f, " - OK\n"); - - bInitFirstEntry = false; - } - else - { - strcat(filepath, " - NOT A VALID MP3"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - } - } - } - else - { - strcpy(filepath, _mp3DirectoryPath); - strcat(filepath, fd.cFileName); - - int32 filepathlen = strlen(filepath); - - if ( filepathlen > 0 ) - { - if ( f ) fprintf(f, "\"%s\"", fd.cFileName); - - if ( filepathlen > 4 ) - { - if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) - { - if ( _ResolveLink(filepath, filepath) ) - { - OutputDebugString("Resolving Link"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); - } - else - { - if ( f ) fprintf(f, " - couldn't resolve shortcut"); - } - - bShortcut = true; - } - else - { - bShortcut = false; - } - } - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - pList->pNext = new tMP3Entry; - - tMP3Entry *e = pList->pNext; - - if ( e == NULL ) - break; - - pList = pList->pNext; - - strcpy(e->aFilename, fd.cFileName); - e->nTrackLength = total_ms; - e->pNext = NULL; - - if ( bShortcut ) - { - e->pLinkPath = new char [MAX_PATH*2]; - strcpy(e->pLinkPath, filepath); - } - else - { - e->pLinkPath = NULL; - } - - nNumMP3s++; - - OutputDebugString(fd.cFileName); - - if ( f ) fprintf(f, " - OK\n"); - } - else - { - strcat(filepath, " - NOT A VALID MP3"); - OutputDebugString(filepath); - - if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); - } - } - } - } - - if ( f ) - { - fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s); - fclose(f); - } - - FindClose(hFind); -} - -static void -_DeleteMP3Entries(void) -{ - tMP3Entry *e = _pMP3List; - - while ( e != NULL ) - { - tMP3Entry *next = e->pNext; - - if ( next == NULL ) - next = NULL; - - if ( e->pLinkPath != NULL ) - { -#ifndef FIX_BUGS - delete e->pLinkPath; // BUG: should be delete [] -#else - delete[] e->pLinkPath; -#endif - e->pLinkPath = NULL; - } - - delete e; - - if ( next ) - e = next; - else - e = NULL; - - nNumMP3s--; - } - - - if ( nNumMP3s != 0 ) - { - OutputDebugString("Not all MP3 entries were deleted"); - nNumMP3s = 0; - } - - _pMP3List = NULL; -} - -static tMP3Entry * -_GetMP3EntryByIndex(uint32 idx) -{ - uint32 n = ( idx < nNumMP3s ) ? idx : 0; - - if ( _pMP3List != NULL ) - { - tMP3Entry *e = _pMP3List; - - for ( uint32 i = 0; i < n; i++ ) - e = e->pNext; - - return e; - - } - - return NULL; -} - -static inline bool -_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) -{ - _CurMP3Index = 0; - - for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) - { - if ( *pPosition >= (*pEntry)->nTrackStreamPos - && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) - { - *pPosition -= (*pEntry)->nTrackStreamPos; - _CurMP3Pos = *pPosition; - - return true; - } - - _CurMP3Index++; - } - - *pPosition = 0; - *pEntry = _pMP3List; - _CurMP3Pos = 0; - _CurMP3Index = 0; - - return false; -} - -bool -cSampleManager::IsMP3RadioChannelAvailable(void) -{ - return nNumMP3s != 0; -} - -void -cSampleManager::ReleaseDigitalHandle(void) -{ - if ( DIG ) - { - prevprovider = curprovider; - release_existing(); - curprovider = -1; - AIL_digital_handle_release(DIG); - } -} - -void -cSampleManager::ReacquireDigitalHandle(void) -{ - if ( DIG ) - { - AIL_digital_handle_reacquire(DIG); - if ( prevprovider != -1 ) - set_new_provider(prevprovider); - } -} - -bool -cSampleManager::Initialise(void) -{ - TRACE("start"); - - if ( _bSampmanInitialised ) - return true; - - { - for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) - { - m_aSamples[i].nOffset = 0; - m_aSamples[i].nSize = 0; - m_aSamples[i].nFrequency = 22050; - 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; - } - - // miles - TRACE("MILES"); - { - curprovider = -1; - prevprovider = -1; - - _usingMilesFast2D = false; - usingEAX=0; - usingEAX3=0; - - _fEffectsLevel = 0.0f; - - _maxSamples = 0; - - opened_provider = NULL; - DIG = NULL; - - for ( int32 i = 0; i < MAXCHANNELS; i++ ) - opened_samples[i] = NULL; - } - - // banks - TRACE("banks"); - { - fpSampleDescHandle = NULL; - fpSampleDataHandle = NULL; - - _nSampleDataEndOffset = 0; - - for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ ) - { - bSampleBankLoaded[i] = false; - nSampleBankDiscStartOffset[i] = 0; - nSampleBankSize[i] = 0; - nSampleBankMemoryStartAddress[i] = 0; - } - } - - // pedsfx - TRACE("pedsfx"); - { - for ( int32 i = 0; i < MAX_PEDSFX; i++ ) - { - nPedSlotSfx[i] = NO_SAMPLE; - nPedSlotSfxAddr[i] = 0; - } - - nCurrentPedSlot = 0; - } - - // channel volume - TRACE("vol"); - { - for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) - nChannelVolume[i] = 0; - } - - TRACE("mss"); - { - AIL_set_redist_directory( "mss" ); - - AIL_startup(); - - AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS); - - DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); - if ( DIG == NULL ) - { - OutputDebugString(AIL_last_error()); - Terminate(); - return false; - } - - add_providers(); - - if ( !InitialiseSampleBanks() ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]); - if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] ) - { - Terminate(); - return false; - } - - nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); - - } - - TRACE("cdrom"); - - S32 tatalms; - char filepath[MAX_PATH]; - - { - m_bInitialised = false; - - while (true) - { - int32 drive = 'C'; - - do - { - char latter[2]; - - latter[0] = drive; - latter[1] = '\0'; - - strcpy(m_szCDRomRootPath, latter); - strcat(m_szCDRomRootPath, ":\\"); - - if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM ) - { - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[0]); - - FILE *f = fopen(filepath, "rb"); - - if ( f ) - { - fclose(f); - - bool bFileNotFound = false; - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[i]); - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - nStreamLength[i] = tatalms; - } - else - { - bFileNotFound = true; - break; - } - } - - if ( !bFileNotFound ) - { - m_bInitialised = true; - break; - } - else - { - m_bInitialised = false; - continue; - } - } - } - - } while ( ++drive <= 'Z' ); - - if ( !m_bInitialised ) - { -#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) - FrontEndMenuManager.WaitForUserCD(); - if ( FrontEndMenuManager.m_bQuitGameNoCD ) - { - Terminate(); - return false; - } - continue; -#else - m_bInitialised = true; -#endif - } - - break; - } - } - -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - // hddaudio - /** - Option for user to play audio files directly from hard disk. - Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory. - Grand Theft Auto III still requires the presence of the PLAY disc when started. - This may give better performance on some machines (though worse on others). - **/ - TRACE("hddaudio 1.1 patch"); - { - int32 streamLength[TOTAL_STREAMED_SOUNDS]; - - bool bFileNotFound = false; - char rootpath[MAX_PATH]; - - strcpy(_aHDDPath, m_szCDRomRootPath); - rootpath[0] = '\0'; - - FILE *f = fopen(StreamedNameTable[0], "rb"); - - if ( f ) - { - fclose(f); - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - { - strcpy(filepath, rootpath); - strcat(filepath, StreamedNameTable[i]); - - mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[0] ) - { - AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); - - AIL_close_stream(mp3Stream[0]); - mp3Stream[0] = NULL; - - streamLength[i] = tatalms; - } - else - { - bFileNotFound = true; - break; - } - } - - } - else - bFileNotFound = true; - - if ( !bFileNotFound ) - { - strcpy(m_szCDRomRootPath, rootpath); - - for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) - nStreamLength[i] = streamLength[i]; - - _bUseHDDAudio = true; - } - else - _bUseHDDAudio = false; - } -#endif - - TRACE("stream"); - { - for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) - { - mp3Stream [i] = NULL; - nStreamPan [i] = 63; - nStreamVolume[i] = 100; - } - } - - for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) - { - opened_2dsamples[i] = AIL_allocate_sample_handle(DIG); - if ( opened_2dsamples[i] ) - { - AIL_init_sample(opened_2dsamples[i]); - AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN); - } - } - - TRACE("providerset"); - { - _bSampmanInitialised = true; - - U32 n = 0; - - while ( n < m_nNumberOfProviders ) - { - if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") ) - { - set_new_provider(n); - break; - } - n++; - } - - if ( n == m_nNumberOfProviders ) - { - Terminate(); - return false; - } - } - - TRACE("bank"); - - LoadSampleBank(SAMPLEBANK_MAIN); - - // mp3 - TRACE("mp3"); - { - nNumMP3s = 0; - - _pMP3List = NULL; - - _FindMP3s(); - - if ( nNumMP3s != 0 ) - { - nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; - - for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) - { - e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; - nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; - } - - time_t t = time(NULL); - tm *localtm; - bool bUseRandomTable; - - if ( t == -1 ) - bUseRandomTable = true; - else - { - bUseRandomTable = false; - localtm = localtime(&t); - } - - int32 randval; - if ( bUseRandomTable ) - randval = AudioManager.GetRandomNumber(1); - else - randval = localtm->tm_sec * localtm->tm_min; - - _CurMP3Index = randval % nNumMP3s; - - tMP3Entry *randmp3 = _pMP3List; - for ( int32 i = randval % nNumMP3s; i > 0; --i) - randmp3 = randmp3->pNext; - - if ( bUseRandomTable ) - _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; - else - { - if ( localtm->tm_sec > 0 ) - { - int32 s = localtm->tm_sec; - _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; - } - else - _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; - } - } - else - _CurMP3Pos = 0; - - _bIsMp3Active = false; - } - - TRACE("end"); - - return true; -} - -void -cSampleManager::Terminate(void) -{ - for ( int32 i = 0; i < MAX_MP3STREAMS; i++ ) - { - if ( mp3Stream[i] ) - { - AIL_pause_stream(mp3Stream[i], 1); - AIL_close_stream(mp3Stream[i]); - mp3Stream[i] = NULL; - } - } - - for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) - { - if ( opened_2dsamples[i] ) - { - AIL_release_sample_handle(opened_2dsamples[i]); - opened_2dsamples[i] = NULL; - } - } - - release_existing(); - - _DeleteMP3Entries(); - - if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 ) - { - AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]); - nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0; - } - - if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 ) - { - AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]); - nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0; - } - - if ( DIG ) - { - AIL_close_digital_driver(DIG); - DIG = NULL; - } - - AIL_shutdown(); - - _bSampmanInitialised = false; -} - -bool -cSampleManager::CheckForAnAudioFileOnCD(void) -{ -#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) - char filepath[MAX_PATH]; - -#if defined(GTA3_1_1_PATCH) - if (_bUseHDDAudio) - strcpy(filepath, _aHDDPath); - else - strcpy(filepath, m_szCDRomRootPath); -#else - strcpy(filepath, m_szCDRomRootPath); -#endif // #if defined(GTA3_1_1_PATCH) - - strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]); - - FILE *f = fopen(filepath, "rb"); - - if ( f ) - { - fclose(f); - - return true; - } - - return false; - -#else - return true; -#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) -} - -char -cSampleManager::GetCDAudioDriveLetter(void) -{ -#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) - if (_bUseHDDAudio) - { - if ( strlen(_aHDDPath) != 0 ) - return _aHDDPath[0]; - else - return '\0'; - } - else - { - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; - else - return '\0'; - } -#else - if ( strlen(m_szCDRomRootPath) != 0 ) - return m_szCDRomRootPath[0]; - else - return '\0'; -#endif -} - -void -cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ? -{ - if ( _bSampmanInitialised ) - { - for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) - { - if ( i < MAXCHANNELS ) - { - if ( opened_samples[i] && GetChannelUsedFlag(i) ) - { - if ( nChannelVolume[i] ) - { - AIL_set_3D_sample_volume(opened_samples[i], - m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14); - } - } - } - else - { - if ( opened_2dsamples[i - MAXCHANNELS] ) - { - if ( GetChannelUsedFlag(i - MAXCHANNELS) ) - { - if ( nChannelVolume[i - MAXCHANNELS] ) - { - AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS], - m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * 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; -} - -bool -cSampleManager::LoadSampleBank(uint8 nBank) -{ - 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) -{ - bSampleBankLoaded[nBank] = false; -} - -bool -cSampleManager::IsSampleBankLoaded(uint8 nBank) -{ - return bSampleBankLoaded[nBank]; -} - -bool -cSampleManager::IsPedCommentLoaded(uint32 nComment) -{ - 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) -{ - 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; - - nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot; - nPedSlotSfx [nCurrentPedSlot] = nComment; - - if ( ++nCurrentPedSlot >= MAX_PEDSFX ) - nCurrentPedSlot = 0; - - return true; -} - -int32 -cSampleManager::GetSampleBaseFrequency(uint32 nSample) -{ - return m_aSamples[nSample].nFrequency; -} - -int32 -cSampleManager::GetSampleLoopStartOffset(uint32 nSample) -{ - return m_aSamples[nSample].nLoopStart; -} - -int32 -cSampleManager::GetSampleLoopEndOffset(uint32 nSample) -{ - return m_aSamples[nSample].nLoopEnd; -} - -uint32 -cSampleManager::GetSampleLength(uint32 nSample) -{ - return m_aSamples[nSample].nSize >> 1; -} - -bool -cSampleManager::UpdateReverb(void) -{ - if ( !usingEAX ) - 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); - - float fRatio; - - if ( normy == 0.0f ) - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - fRatio = 0.3f; - } - } - else - { - if ( normx == 0.0f ) - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = 0.5f; - } - else - { - if ( normz == 0.0f ) - fRatio = 0.3f; - else - fRatio = (normy+normx+normz) / 3.0f; - } - } - - fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); - - if ( fRatio == _fPrevEaxRatioDestination ) - return false; - - if ( usingEAX3 ) - { - if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) - { - AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); - _fEffectsLevel = 1.0f - fRatio * 0.5f; - } - } - else - { - if ( _usingMilesFast2D ) - _fEffectsLevel = (1.0f - fRatio) * 0.4f; - else - _fEffectsLevel = (1.0f - fRatio) * 0.7f; - } - - _fPrevEaxRatioDestination = fRatio; - - return true; -} - -void -cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( usingEAX ) - { - if ( nReverbFlag != 0 ) - { - if ( !b2d ) - AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel); - } - else - { - if ( !b2d ) - AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f); - } - } -} - -bool -cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - int32 addr; - - if ( nSfx < SAMPLEBANK_MAX ) - { - if ( !IsSampleBankLoaded(nBank) ) - return false; - - addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; - } - else - { - if ( !IsPedCommentLoaded(nSfx) ) - return false; - - int32 slot = _GetPedCommentSlot(nSfx); - - addr = nPedSlotSfxAddr[slot]; - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - { - AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize); - return true; - } - else - return false; - } - else - { - AILSOUNDINFO info; - - info.format = WAVE_FORMAT_PCM; - info.data_ptr = (void *)addr; - info.channels = 1; - info.data_len = m_aSamples[nSfx].nSize; - info.rate = m_aSamples[nSfx].nFrequency; - info.bits = 16; - - if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 ) - { - OutputDebugString(AIL_last_error()); - return false; - } - - return true; - } -} - -void -cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) -{ - 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; - } - - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); - -} - -void -cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) -{ - if ( opened_samples[nChannel] ) - AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ); -} - -void -cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) -{ - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin); -} - -void -cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) -{ - uint32 vol = nVolume; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - - switch ( nChannel ) - { - case CHANNEL2D: - { - 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; - } - - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - { - AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS], - m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); - } - - break; - } - } -} - -void -cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) -{ - switch ( nChannel ) - { - case CHANNEL2D: - { -#ifndef FIX_BUGS - if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG -#else - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) -#endif - AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan); - - break; - } - } -} - -void -cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq); - } - else - { - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq); - } -} - -void -cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd); - } - else - { - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd); - } -} - -void -cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount); - } - else - { - if ( opened_samples[nChannel] ) - AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount); - } -} - -bool -cSampleManager::GetChannelUsedFlag(uint32 nChannel) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING; - else - return false; - } - else - { - if ( opened_samples[nChannel] ) - return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING; - else - return false; - } - -} - -void -cSampleManager::StartChannel(uint32 nChannel) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]); - } - else - { - if ( opened_samples[nChannel] ) - AIL_start_3D_sample(opened_samples[nChannel]); - } -} - -void -cSampleManager::StopChannel(uint32 nChannel) -{ - bool b2d = false; - - switch ( nChannel ) - { - case CHANNEL2D: - { - b2d = true; - break; - } - } - - if ( b2d ) - { - if ( opened_2dsamples[nChannel - MAXCHANNELS] ) - AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]); - } - else - { - if ( opened_samples[nChannel] ) - { - if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING ) - AIL_end_3D_sample(opened_samples[nChannel]); - } - } -} - -void -cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( nFile < TOTAL_STREAMED_SOUNDS ) - { - if ( mp3Stream[nStream] ) - { - AIL_pause_stream(mp3Stream[nStream], 1); - AIL_close_stream(mp3Stream[nStream]); - } - - char filepath[MAX_PATH]; - - strcpy(filepath, m_szCDRomRootPath); - strcat(filepath, StreamedNameTable[nFile]); - - mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); - - if ( mp3Stream[nStream] ) - { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_service_stream(mp3Stream[nStream], 1); - } - else - OutputDebugString(AIL_last_error()); - } - } -} - -void -cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0); - } -} - -void -cSampleManager::StartPreloadedStreamedFile(uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - AIL_start_stream(mp3Stream[nStream]); - } -} - -bool -cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) -{ - uint32 position = nPos; - char filename[MAX_PATH]; - - if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS ) - { - if ( mp3Stream[nStream] ) - { - AIL_pause_stream(mp3Stream[nStream], 1); - AIL_close_stream(mp3Stream[nStream]); - } - - if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) - { - uint32 i = 0; - do { - if(i != 0 || _bIsMp3Active) { - if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; - - _CurMP3Pos = 0; - - tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); - - if(mp3) { - mp3 = _pMP3List; - if(mp3 == NULL) { - _bIsMp3Active = false; - nFile = 0; - strcpy(filename, m_szCDRomRootPath); - strcat(filename, StreamedNameTable[nFile]); - - mp3Stream[nStream] = - AIL_open_stream(DIG, filename, 0); - if(mp3Stream[nStream]) { - AIL_set_stream_loop_count( - mp3Stream[nStream], 1); - AIL_set_stream_ms_position( - mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], - 0); - return true; - } - - return false; - } - } - - if(mp3->pLinkPath != NULL) - mp3Stream[nStream] = - AIL_open_stream(DIG, mp3->pLinkPath, 0); - else { - strcpy(filename, _mp3DirectoryPath); - strcat(filename, mp3->aFilename); - - mp3Stream[nStream] = - AIL_open_stream(DIG, filename, 0); - } - - if(mp3Stream[nStream]) { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_set_stream_ms_position(mp3Stream[nStream], 0); - AIL_pause_stream(mp3Stream[nStream], 0); - return true; - } - - _bIsMp3Active = false; - continue; - } - if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) - position = 0; - - tMP3Entry *e; - if ( !_GetMP3PosFromStreamPos(&position, &e) ) - { - if ( e == NULL ) - { - nFile = 0; - strcpy(filename, m_szCDRomRootPath); - strcat(filename, StreamedNameTable[nFile]); - mp3Stream[nStream] = - AIL_open_stream(DIG, filename, 0); - if(mp3Stream[nStream]) { - AIL_set_stream_loop_count( - mp3Stream[nStream], 1); - AIL_set_stream_ms_position( - mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], 0); - return true; - } - - return false; - } - } - - if ( e->pLinkPath != NULL ) - mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0); - else - { - strcpy(filename, _mp3DirectoryPath); - strcat(filename, e->aFilename); - - mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); - } - - if ( mp3Stream[nStream] ) - { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_set_stream_ms_position(mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], 0); - - _bIsMp3Active = true; - - return true; - } - - _bIsMp3Active = false; - - } while(++i < nNumMP3s); - - position = 0; - nFile = 0; - } - - strcpy(filename, m_szCDRomRootPath); - strcat(filename, StreamedNameTable[nFile]); - - mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); - if ( mp3Stream[nStream] ) - { - AIL_set_stream_loop_count(mp3Stream[nStream], 1); - AIL_set_stream_ms_position(mp3Stream[nStream], position); - AIL_pause_stream(mp3Stream[nStream], 0); - return true; - } - } - - return false; -} - -void -cSampleManager::StopStreamedFile(uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - { - AIL_pause_stream(mp3Stream[nStream], 1); - - AIL_close_stream(mp3Stream[nStream]); - mp3Stream[nStream] = NULL; - - if ( nStream == 0 ) - _bIsMp3Active = false; - } - } -} - -int32 -cSampleManager::GetStreamedFilePosition(uint8 nStream) -{ - S32 currentms; - - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - { - if ( _bIsMp3Active ) - { - tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); - - if ( mp3 != NULL ) - { - AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); - return currentms + mp3->nTrackStreamPos; - } - else - return 0; - } - else - { - AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); - return currentms; - } - } - } - - return 0; -} - -void -cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) -{ - uint8 vol = nVolume; - - if ( m_bInitialised ) - { - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; - - nStreamVolume[nStream] = vol; - nStreamPan[nStream] = nPan; - - if ( mp3Stream[nStream] ) - { - if ( nEffectFlag ) - AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); - else - AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14); - - AIL_set_stream_pan(mp3Stream[nStream], nPan); - } - } -} - -int32 -cSampleManager::GetStreamedFileLength(uint8 nStream) -{ - if ( m_bInitialised ) - return nStreamLength[nStream]; - - return 0; -} - -bool -cSampleManager::IsStreamPlaying(uint8 nStream) -{ - if ( m_bInitialised ) - { - if ( mp3Stream[nStream] ) - { - if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING ) - return true; - else - return false; - } - } - - return false; -} - -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); - _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; -} 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; + + // 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 +#include + +typedef struct +{ + std::string strDeviceName; + int iMajorVersion; + int iMinorVersion; + unsigned int uiSourceCount; + std::vector *pvstrExtensions; + bool bSelected; +} ALDEVICEINFO, *LPALDEVICEINFO; + +class ALDeviceList +{ +private: + std::vector vDeviceInfo; + int defaultDeviceIndex; + int filterIndex; + +public: + ALDeviceList (); + ~ALDeviceList (); + int GetNumDevices(); + char *GetDeviceName(int index); + void GetDeviceVersion(int index, int *major, int *minor); + unsigned int GetMaxNumSources(int index); + bool IsExtensionSupported(int index, char *szExtName); + int GetDefaultDevice(); + void FilterDevicesMinVer(int major, int minor); + void FilterDevicesMaxVer(int major, int minor); + void FilterDevicesExtension(char *szExtName); + void ResetFilters(); + int GetFirstFilteredDevice(); + int GetNextFilteredDevice(); + +private: + unsigned int GetMaxNumSources(); +}; +#endif + +#endif // ALDEVICELIST_H \ No newline at end of file diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp new file mode 100644 index 00000000..d8b50161 --- /dev/null +++ b/src/audio/oal/channel.cpp @@ -0,0 +1,209 @@ +#include "channel.h" + +#ifdef AUDIO_OAL +#include "sampman.h" + +extern bool IsFXSupported(); + +CChannel::CChannel() +{ + alChannel = AL_NONE; + alFilter = AL_FILTER_NULL; + SetDefault(); +} + +void CChannel::SetDefault() +{ + Buffer = AL_NONE; + + Pitch = 1.0f; + Gain = 1.0f; + Mix = 0.0f; + + Position[0] = 0.0f; Position[1] = 0.0f; Position[2] = 0.0f; + Distances[0] = 0.0f; Distances[1] = FLT_MAX; + LoopCount = 1; + LoopPoints[0] = 0; LoopPoints[1] = -1; + + Frequency = MAX_FREQ; +} + +void CChannel::Reset() +{ + ClearBuffer(); + SetDefault(); +} + +void CChannel::Init(bool Is2D) +{ + ASSERT(!HasSource()); + alGenSources(1, &alChannel); + if ( HasSource() ) + { + alSourcei(alChannel, AL_SOURCE_RELATIVE, AL_TRUE); + if ( IsFXSupported() ) + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + + if ( Is2D ) + { + alSource3f(alChannel, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef (alChannel, AL_GAIN, 1.0f); + } + else + { + if ( IsFXSupported() ) + alGenFilters(1,&alFilter); + } + } +} + +void CChannel::Term() +{ + Stop(); + if ( HasSource() ) + { + if ( IsFXSupported() ) + { + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + + if(alFilter != AL_FILTER_NULL) + alDeleteFilters(1,&alFilter); + } + + alDeleteSources(1, &alChannel); + } + alChannel = AL_NONE; + alFilter = AL_FILTER_NULL; +} + +void CChannel::Start() +{ + if ( !HasSource() ) return; + + if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 ) + alBufferiv(Buffer, AL_LOOP_POINTS_SOFT, LoopPoints); + alSourcei (alChannel, AL_BUFFER, Buffer); + alSourcePlay(alChannel); +} + +void CChannel::Stop() +{ + if ( HasSource() ) + alSourceStop(alChannel); + + Reset(); +} + +bool CChannel::HasSource() +{ + return alChannel != AL_NONE; +} + +bool CChannel::IsUsed() +{ + if ( HasSource() ) + { + ALint sourceState; + alGetSourcei(alChannel, AL_SOURCE_STATE, &sourceState); + return sourceState == AL_PLAYING; + } + return false; +} + +void CChannel::SetPitch(float pitch) +{ + if ( !HasSource() ) return; + alSourcef(alChannel, AL_PITCH, pitch); +} + +void CChannel::SetGain(float gain) +{ + if ( !HasSource() ) return; + alSourcef(alChannel, AL_GAIN, gain); +} + +void CChannel::SetVolume(int32 vol) +{ + SetGain(ALfloat(vol) / MAX_VOLUME); +} + +void CChannel::SetSampleID(uint32 nSfx) +{ + Sample = nSfx; +} + +void CChannel::SetFreq(int32 freq) +{ + Frequency = freq; +} + +void CChannel::SetCurrentFreq(uint32 freq) +{ + SetPitch(ALfloat(freq) / Frequency); +} + +void CChannel::SetLoopCount(int32 loopCount) // fake. TODO: +{ + if ( !HasSource() ) return; + alSourcei(alChannel, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE); +} + +void CChannel::SetLoopPoints(ALint start, ALint end) +{ + LoopPoints[0] = start; + LoopPoints[1] = end; +} + +void CChannel::SetPosition(float x, float y, float z) +{ + if ( !HasSource() ) return; + alSource3f(alChannel, AL_POSITION, x, y, z); +} + +void CChannel::SetDistances(float max, float min) +{ + if ( !HasSource() ) return; + alSourcef (alChannel, AL_MAX_DISTANCE, max); + alSourcef (alChannel, AL_REFERENCE_DISTANCE, min); + alSourcef (alChannel, AL_MAX_GAIN, 1.0f); + alSourcef (alChannel, AL_ROLLOFF_FACTOR, 1.0f); +} + +void CChannel::SetPan(uint32 pan) +{ + SetPosition((pan-63)/64.0f, 0.0f, sqrtf(1.0f-SQR((pan-63)/64.0f))); +} + +void CChannel::SetBuffer(ALuint buffer) +{ + Buffer = buffer; +} + +void CChannel::ClearBuffer() +{ + if ( !HasSource() ) return; + SetBuffer(AL_NONE); + alSourcei(alChannel, AL_BUFFER, AL_NONE); +} + +void CChannel::SetReverbMix(ALuint slot, float mix) +{ + if ( !IsFXSupported() ) return; + if ( !HasSource() ) return; + if ( alFilter == AL_FILTER_NULL ) return; + + Mix = mix; + EAX3_SetReverbMix(alFilter, mix); + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); +} + +void CChannel::UpdateReverb(ALuint slot) +{ + if ( !IsFXSupported() ) return; + if ( !HasSource() ) return; + if ( alFilter == AL_FILTER_NULL ) return; + EAX3_SetReverbMix(alFilter, Mix); + alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); +} + +#endif \ No newline at end of file diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h new file mode 100644 index 00000000..d9ffea22 --- /dev/null +++ b/src/audio/oal/channel.h @@ -0,0 +1,51 @@ +#pragma once +#include "common.h" + +#ifdef AUDIO_OAL +#include "oal/oal_utils.h" +#include +#include +#include + + +class CChannel +{ + ALuint alChannel; + ALuint alFilter; + ALuint Buffer; + float Pitch, Gain; + float Mix; + int32 Frequency; + float Position[3]; + float Distances[2]; + int32 LoopCount; + ALint LoopPoints[2]; + uint32 Sample; +public: + CChannel(); + void SetDefault(); + void Reset(); + void Init(bool Is2D = false); + void Term(); + void Start(); + void Stop(); + bool HasSource(); + bool IsUsed(); + void SetPitch(float pitch); + void SetGain(float gain); + void SetVolume(int32 vol); + void SetSampleID(uint32 nSfx); + void SetFreq(int32 freq); + void SetCurrentFreq(uint32 freq); + void SetLoopCount(int32 loopCount); // fake + void SetLoopPoints(ALint start, ALint end); + void SetPosition(float x, float y, float z); + void SetDistances(float max, float min); + void SetPan(uint32 pan); + void SetBuffer(ALuint buffer); + void ClearBuffer(); + void SetReverbMix(ALuint slot, float mix); + void UpdateReverb(ALuint slot); +}; + +#endif \ No newline at end of file diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp new file mode 100644 index 00000000..a2df61c1 --- /dev/null +++ b/src/audio/oal/oal_utils.cpp @@ -0,0 +1,176 @@ +#include "oal_utils.h" + +#ifdef AUDIO_OAL + +LPALGENEFFECTS alGenEffects; +LPALDELETEEFFECTS alDeleteEffects; +LPALISEFFECT alIsEffect; +LPALEFFECTI alEffecti; +LPALEFFECTIV alEffectiv; +LPALEFFECTF alEffectf; +LPALEFFECTFV alEffectfv; +LPALGETEFFECTI alGetEffecti; +LPALGETEFFECTIV alGetEffectiv; +LPALGETEFFECTF alGetEffectf; +LPALGETEFFECTFV alGetEffectfv; +LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +LPALGENFILTERS alGenFilters; +LPALDELETEFILTERS alDeleteFilters; +LPALISFILTER alIsFilter; +LPALFILTERI alFilteri; +LPALFILTERIV alFilteriv; +LPALFILTERF alFilterf; +LPALFILTERFV alFilterfv; +LPALGETFILTERI alGetFilteri; +LPALGETFILTERIV alGetFilteriv; +LPALGETFILTERF alGetFilterf; +LPALGETFILTERFV alGetFilterfv; + + +void EFXInit() +{ + if (alIsExtensionPresent((ALchar*)"EAX3.0")) + DEV("\nBIG EAX IN TOWN\n"); + else + DEV("\nNO EAX\n"); + + + /* Define a macro to help load the function pointers. */ +#define LOAD_PROC(T, x) ((x) = (T)alGetProcAddress(#x)) + LOAD_PROC(LPALGENEFFECTS, alGenEffects); + LOAD_PROC(LPALDELETEEFFECTS, alDeleteEffects); + LOAD_PROC(LPALISEFFECT, alIsEffect); + LOAD_PROC(LPALEFFECTI, alEffecti); + LOAD_PROC(LPALEFFECTIV, alEffectiv); + LOAD_PROC(LPALEFFECTF, alEffectf); + LOAD_PROC(LPALEFFECTFV, alEffectfv); + LOAD_PROC(LPALGETEFFECTI, alGetEffecti); + LOAD_PROC(LPALGETEFFECTIV, alGetEffectiv); + LOAD_PROC(LPALGETEFFECTF, alGetEffectf); + LOAD_PROC(LPALGETEFFECTFV, alGetEffectfv); + + LOAD_PROC(LPALGENFILTERS, alGenFilters); + LOAD_PROC(LPALDELETEFILTERS, alDeleteFilters); + LOAD_PROC(LPALISFILTER, alIsFilter); + LOAD_PROC(LPALFILTERI, alFilteri); + LOAD_PROC(LPALFILTERIV, alFilteriv); + LOAD_PROC(LPALFILTERF, alFilterf); + LOAD_PROC(LPALFILTERFV, alFilterfv); + LOAD_PROC(LPALGETFILTERI, alGetFilteri); + LOAD_PROC(LPALGETFILTERIV, alGetFilteriv); + LOAD_PROC(LPALGETFILTERF, alGetFilterf); + LOAD_PROC(LPALGETFILTERFV, alGetFilterfv); + + LOAD_PROC(LPALGENAUXILIARYEFFECTSLOTS, alGenAuxiliaryEffectSlots); + LOAD_PROC(LPALDELETEAUXILIARYEFFECTSLOTS, alDeleteAuxiliaryEffectSlots); + LOAD_PROC(LPALISAUXILIARYEFFECTSLOT, alIsAuxiliaryEffectSlot); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTI, alAuxiliaryEffectSloti); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTIV, alAuxiliaryEffectSlotiv); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTF, alAuxiliaryEffectSlotf); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTFV, alAuxiliaryEffectSlotfv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTI, alGetAuxiliaryEffectSloti); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTIV, alGetAuxiliaryEffectSlotiv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTF, alGetAuxiliaryEffectSlotf); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); +#undef LOAD_PROC +} + + +void SetEffectsLevel(ALuint uiFilter, float level) +{ + alFilteri(uiFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + alFilterf(uiFilter, AL_LOWPASS_GAIN, 1.0f); + alFilterf(uiFilter, AL_LOWPASS_GAINHF, level); +} + +static inline float gain_to_mB(float gain) +{ + return (gain > 1e-5f) ? (float)(log10f(gain) * 2000.0f) : -10000l; +} + +static inline float mB_to_gain(float millibels) +{ + return (millibels > -10000.0f) ? powf(10.0f, millibels/2000.0f) : 0.0f; +} + +static inline FLOAT clampF(FLOAT val, FLOAT minval, FLOAT maxval) +{ + if(val >= maxval) return maxval; + if(val <= minval) return minval; + return val; +} + +void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props) +{ + alEffecti (effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); + alEffectf (effect, AL_EAXREVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f)); + alEffectf (effect, AL_EAXREVERB_DIFFUSION, props->flEnvironmentDiffusion); + alEffectf (effect, AL_EAXREVERB_GAIN, mB_to_gain((float)props->lRoom)); + alEffectf (effect, AL_EAXREVERB_GAINHF, mB_to_gain((float)props->lRoomHF)); + alEffectf (effect, AL_EAXREVERB_GAINLF, mB_to_gain((float)props->lRoomLF)); + alEffectf (effect, AL_EAXREVERB_DECAY_TIME, props->flDecayTime); + alEffectf (effect, AL_EAXREVERB_DECAY_HFRATIO, props->flDecayHFRatio); + alEffectf (effect, AL_EAXREVERB_DECAY_LFRATIO, props->flDecayLFRatio); + alEffectf (effect, AL_EAXREVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN)); + alEffectf (effect, AL_EAXREVERB_REFLECTIONS_DELAY, props->flReflectionsDelay); + alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, &props->vReflectionsPan.x); + alEffectf (effect, AL_EAXREVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN)); + alEffectf (effect, AL_EAXREVERB_LATE_REVERB_DELAY, props->flReverbDelay); + alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, &props->vReverbPan.x); + alEffectf (effect, AL_EAXREVERB_ECHO_TIME, props->flEchoTime); + alEffectf (effect, AL_EAXREVERB_ECHO_DEPTH, props->flEchoDepth); + alEffectf (effect, AL_EAXREVERB_MODULATION_TIME, props->flModulationTime); + alEffectf (effect, AL_EAXREVERB_MODULATION_DEPTH, props->flModulationDepth); + alEffectf (effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)); + alEffectf (effect, AL_EAXREVERB_HFREFERENCE, props->flHFReference); + alEffectf (effect, AL_EAXREVERB_LFREFERENCE, props->flLFReference); + alEffectf (effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor); + alEffecti (effect, AL_EAXREVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE); +} + +void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props) +{ + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + + alEffectf(effect, AL_REVERB_DENSITY, clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f)); + alEffectf(effect, AL_REVERB_DIFFUSION, props->flEnvironmentDiffusion); + alEffectf(effect, AL_REVERB_GAIN, mB_to_gain((float)props->lRoom)); + alEffectf(effect, AL_REVERB_GAINHF, mB_to_gain((float)props->lRoomHF)); + alEffectf(effect, AL_REVERB_DECAY_TIME, props->flDecayTime); + alEffectf(effect, AL_REVERB_DECAY_HFRATIO, props->flDecayHFRatio); + alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN)); + alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, props->flReflectionsDelay); + alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN)); + alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, props->flReverbDelay); + alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)); + alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, props->flRoomRolloffFactor); + alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE); +} + +void EAX3_SetReverbMix(ALuint filter, float mix) +{ + //long vol=(long)linear_to_dB(mix); + //DSPROPERTY_EAXBUFFER_ROOMHF, + //DSPROPERTY_EAXBUFFER_ROOM, + //DSPROPERTY_EAXBUFFER_REVERBMIX, + + long mbvol = gain_to_mB(mix); + float mb = mbvol; + float mbhf = mbvol; + + alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + alFilterf(filter, AL_LOWPASS_GAIN, mB_to_gain(Min(mb, 0.0f))); + alFilterf(filter, AL_LOWPASS_GAINHF, mB_to_gain(mbhf)); +} + +#endif \ No newline at end of file diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h new file mode 100644 index 00000000..af45a944 --- /dev/null +++ b/src/audio/oal/oal_utils.h @@ -0,0 +1,48 @@ +#pragma once +#include "common.h" + +#ifdef AUDIO_OAL +#include "eax.h" +#include "AL/efx.h" + + +void EFXInit(); +void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); +void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props); +void EAX3_SetReverbMix(ALuint filter, float mix); +void SetEffectsLevel(ALuint uiFilter, float level); + +extern LPALGENEFFECTS alGenEffects; +extern LPALDELETEEFFECTS alDeleteEffects; +extern LPALISEFFECT alIsEffect; +extern LPALEFFECTI alEffecti; +extern LPALEFFECTIV alEffectiv; +extern LPALEFFECTF alEffectf; +extern LPALEFFECTFV alEffectfv; +extern LPALGETEFFECTI alGetEffecti; +extern LPALGETEFFECTIV alGetEffectiv; +extern LPALGETEFFECTF alGetEffectf; +extern LPALGETEFFECTFV alGetEffectfv; +extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +extern LPALGENFILTERS alGenFilters; +extern LPALDELETEFILTERS alDeleteFilters; +extern LPALISFILTER alIsFilter; +extern LPALFILTERI alFilteri; +extern LPALFILTERIV alFilteriv; +extern LPALFILTERF alFilterf; +extern LPALFILTERFV alFilterfv; +extern LPALGETFILTERI alGetFilteri; +extern LPALGETFILTERIV alGetFilteriv; +extern LPALGETFILTERF alGetFilterf; +extern LPALGETFILTERFV alGetFilterfv; +#endif diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp new file mode 100644 index 00000000..a65c9794 --- /dev/null +++ b/src/audio/oal/stream.cpp @@ -0,0 +1,118 @@ +#include "stream.h" +#include "common.h" + +#ifdef AUDIO_OAL + +void CStream::Initialise() +{ + //mpg123_init(); +} + +void CStream::Terminate() +{ + //mpg123_exit(); +} + +CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) : + m_alSource(source), + m_alBuffers(buffers), + m_nBitRate(0), + m_nFormat(0), + m_nFreq(0), + m_nLength(0), + m_nLengthMS(0), + m_nBufferSize(0), + m_pBuffer(NULL), + m_bIsOpened(false), + m_bPaused(true) + +{ + strcpy(m_aFilename, filename); + + //DEV("Stream %s\n", m_aFilename); + + /* + if ( true ) + { + m_nBitRate = (wBitsPerSample * nChannels * wfex.nSamplesPerSec)/1000; + m_nLength = ulDataSize; + m_nLengthMS = m_nLength*8 / m_nBitRate; + m_nBufferSize = nAvgBytesPerSec >> 2; + m_nBufferSize -= (m_nLength % wfex.nBlockAlign); + m_pBuffer = malloc(m_nBufferSize); + m_bIsOpened = true; + return; + }*/ +} + +CStream::~CStream() +{ + Delete(); +} + +void CStream::Delete() +{ + if ( m_pBuffer ) + { + free(m_pBuffer); + m_pBuffer = NULL; + } +} + +bool CStream::IsOpened() +{ + return m_bIsOpened; +} + +bool CStream::IsPlaying() +{ + return false; +} + +void CStream::SetPause(bool bPause) +{ +} + +void CStream::SetVolume(uint32 nVol) +{ + +} + +void CStream::SetPan(uint8 nPan) +{ +} + +void CStream::SetPos(uint32 nPos) +{ +} + +uint32 CStream::GetPos() +{ + return 0; +} + +uint32 CStream::GetLength() +{ + return m_nLengthMS; +} + +bool CStream::Setup() +{ + if ( !IsOpened() ) + return false; + + return IsOpened(); +} + +void CStream::Start() +{ + +} + +void CStream::Update() +{ + if ( !IsOpened() ) + return; +} + +#endif \ No newline at end of file diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h new file mode 100644 index 00000000..666d42e0 --- /dev/null +++ b/src/audio/oal/stream.h @@ -0,0 +1,57 @@ +#pragma once +#include "common.h" + +#ifdef AUDIO_OAL +#include + +#define NUM_STREAMBUFFERS 5 +#define STREAMBUFFER_SIZE 0x4000 + +class CStream +{ + char m_aFilename[128]; + ALuint &m_alSource; + ALuint (&m_alBuffers)[NUM_STREAMBUFFERS]; + + bool m_bIsOpened; + bool m_bPaused; + + uint32 m_nLength; + uint32 m_nLengthMS; + uint32 m_nBitRate; + + unsigned long m_nFormat; + unsigned long m_nFreq; + + uint32 m_nBufferSize; + void *m_pBuffer; + + ALint iTotalBuffersProcessed; + + bool FillBuffer(ALuint alBuffer); + int32 FillBuffers(); +public: + static void Initialise(); + static void Terminate(); + + CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]); + ~CStream(); + + void Delete(); + + bool IsOpened(); + bool IsPlaying(); + void SetPause (bool bPause); + void SetVolume(uint32 nVol); + void SetPan (uint8 nPan); + void SetPos (uint32 nPos); + + uint32 GetPos(); + uint32 GetLength(); + + bool Setup(); + void Start(); + void Update(void); +}; + +#endif \ No newline at end of file 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 -#include -#include -//#include -#include -#include -#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/sampman_miles.cpp b/src/audio/sampman_miles.cpp new file mode 100644 index 00000000..caf2917f --- /dev/null +++ b/src/audio/sampman_miles.cpp @@ -0,0 +1,2311 @@ +#include "common.h" + +#ifdef AUDIO_MSS +#include +#include +#include + +#include + +#include "eax.h" +#include "eax-util.h" +#include "mss.h" + +#include "sampman.h" +#include "AudioManager.h" +#include "MusicManager.h" +#include "Frontend.h" +#include "Timer.h" + + +#pragma comment( lib, "mss32.lib" ) + +cSampleManager SampleManager; +uint32 BankStartOffset[MAX_SAMPLEBANKS]; +/////////////////////////////////////////////////////////////// + +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; + +uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; + +uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; + +/////////////////////////////////////////////////////////////// +struct tMP3Entry +{ + char aFilename[MAX_PATH]; + + uint32 nTrackLength; + uint32 nTrackStreamPos; + + tMP3Entry *pNext; + char *pLinkPath; +}; + +uint32 nNumMP3s; +tMP3Entry *_pMP3List; +char _mp3DirectoryPath[MAX_PATH]; +HSTREAM mp3Stream [MAX_STREAMS]; +int8 nStreamPan [MAX_STREAMS]; +int8 nStreamVolume[MAX_STREAMS]; +uint32 _CurMP3Index; +int32 _CurMP3Pos; +bool _bIsMp3Active; + +#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) +bool _bUseHDDAudio; +char _aHDDPath[MAX_PATH]; +#endif +/////////////////////////////////////////////////////////////// + + +bool _bSampmanInitialised = false; + +// +// Miscellaneous globals / defines + +// 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; + +S32 prevprovider=-1; +S32 curprovider=-1; +S32 usingEAX=0; +S32 usingEAX3=0; +HPROVIDER opened_provider=0; +H3DSAMPLE opened_samples[MAXCHANNELS] = {0}; +HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0}; +HDIGDRIVER DIG; +S32 speaker_type=0; + +U32 _maxSamples; +float _fPrevEaxRatioDestination; +bool _usingMilesFast2D; +float _fEffectsLevel; + + +struct +{ + HPROVIDER id; + char name[80]; +}providers[MAXPROVIDERS]; + +typedef struct provider_stuff +{ + char* name; + HPROVIDER id; +} provider_stuff; + + +static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2) +{ + return( _stricmp(s1->name,s2->name) ); +} + +static void +add_providers() +{ + provider_stuff pi[MAXPROVIDERS]; + U32 n,i,j; + + SampleManager.SetNum3DProvidersAvailable(0); + + HPROENUM next = HPROENUM_FIRST; + + n=0; + while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n MAXCHANNELS ) + _maxSamples = MAXCHANNELS; + + SampleManager.SetSpeakerConfig(speaker_type); + + //obtain a 3D sample handles + for ( U32 i = 0; i < _maxSamples; ++i ) + { + opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider); + if ( opened_samples[i] != NULL ) + AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f); + } + + return true; + } + } + + return false; +} + +cSampleManager::cSampleManager(void) : + m_nNumberOfProviders(0) +{ + ; +} + +cSampleManager::~cSampleManager(void) +{ + +} + +void +cSampleManager::SetSpeakerConfig(int32 which) +{ + switch ( which ) + { + case 1: + speaker_type=AIL_3D_2_SPEAKER; + break; + + case 2: + speaker_type=AIL_3D_HEADPHONE; + break; + + case 3: + speaker_type=AIL_3D_4_SPEAKER; + break; + + default: + return; + break; + } + + if (opened_provider) + AIL_set_3D_speaker_type(opened_provider, speaker_type); +} + +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) +{ + S32 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; +} + +static bool +_ResolveLink(char const *path, char *out) +{ + IShellLink* psl; + WIN32_FIND_DATA fd; + char filepath[MAX_PATH]; + + CoInitialize(NULL); + + if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) )) + { + IPersistFile *ppf; + + if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) + { + WCHAR wpath[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); + + if (SUCCEEDED(ppf->Load(wpath, STGM_READ))) + { + /* Resolve the link */ + if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH))) + { + strcpy(filepath, path); + + if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY))) + { + OutputDebugString(fd.cFileName); + + strcpy(out, filepath); + // FIX: Release the objects. Taken from SA. +#ifdef FIX_BUGS + ppf->Release(); + psl->Release(); +#endif + return true; + } + } + } + + ppf->Release(); + } + psl->Release(); + } + + return false; +} + +static void +_FindMP3s(void) +{ + tMP3Entry *pList; + bool bShortcut; + bool bInitFirstEntry; + HANDLE hFind; + char path[MAX_PATH]; + char filepath[MAX_PATH*2]; + S32 total_ms; + WIN32_FIND_DATA fd; + + + if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 ) + { + GetLastError(); + return; + } + + OutputDebugString("Finding MP3s..."); + strcpy(path, _mp3DirectoryPath); + strcat(path, "\\MP3\\"); + + strcpy(_mp3DirectoryPath, path); + OutputDebugString(_mp3DirectoryPath); + + strcat(path, "*"); + + hFind = FindFirstFile(path, &fd); + + if ( hFind == INVALID_HANDLE_VALUE ) + { + GetLastError(); + return; + } + + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( filepathlen <= 0) + { + FindClose(hFind); + return; + } + + FILE *f = fopen("MP3\\MP3Report.txt", "w"); + + if ( f ) + { + fprintf(f, "MP3 Report File\n\n"); + fprintf(f, "\"%s\"", fd.cFileName); + } + + + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); + } + else + { + if ( f ) fprintf(f, " - couldn't resolve shortcut"); + } + + bShortcut = true; + } + else + bShortcut = false; + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL ) + { + FindClose(hFind); + + if ( f ) + fclose(f); + + return; + } + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + + _pMP3List->pNext = NULL; + + pList = _pMP3List; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char[MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + if ( f ) fprintf(f, " - OK\n"); + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); + + bInitFirstEntry = true; + } + + while ( true ) + { + if ( !FindNextFile(hFind, &fd) ) + break; + + if ( bInitFirstEntry ) + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( f ) fprintf(f, "\"%s\"", fd.cFileName); + + if ( filepathlen > 0 ) + { + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); + } + else + { + if ( f ) fprintf(f, " - couldn't resolve shortcut"); + } + + bShortcut = true; + } + else + { + bShortcut = false; + + if ( filepathlen > MAX_PATH ) + { + if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath); + + continue; + } + } + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + OutputDebugString(fd.cFileName); + + _pMP3List = new tMP3Entry; + + if ( _pMP3List == NULL) + break; + + nNumMP3s = 1; + + strcpy(_pMP3List->aFilename, fd.cFileName); + + _pMP3List->nTrackLength = total_ms; + _pMP3List->pNext = NULL; + + if ( bShortcut ) + { + _pMP3List->pLinkPath = new char [MAX_PATH*2]; + strcpy(_pMP3List->pLinkPath, filepath); + } + else + { + _pMP3List->pLinkPath = NULL; + } + + pList = _pMP3List; + + if ( f ) fprintf(f, " - OK\n"); + + bInitFirstEntry = false; + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); + } + } + } + else + { + strcpy(filepath, _mp3DirectoryPath); + strcat(filepath, fd.cFileName); + + int32 filepathlen = strlen(filepath); + + if ( filepathlen > 0 ) + { + if ( f ) fprintf(f, "\"%s\"", fd.cFileName); + + if ( filepathlen > 4 ) + { + if ( !strcmp(&filepath[filepathlen - 4], ".lnk") ) + { + if ( _ResolveLink(filepath, filepath) ) + { + OutputDebugString("Resolving Link"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath); + } + else + { + if ( f ) fprintf(f, " - couldn't resolve shortcut"); + } + + bShortcut = true; + } + else + { + bShortcut = false; + } + } + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + pList->pNext = new tMP3Entry; + + tMP3Entry *e = pList->pNext; + + if ( e == NULL ) + break; + + pList = pList->pNext; + + strcpy(e->aFilename, fd.cFileName); + e->nTrackLength = total_ms; + e->pNext = NULL; + + if ( bShortcut ) + { + e->pLinkPath = new char [MAX_PATH*2]; + strcpy(e->pLinkPath, filepath); + } + else + { + e->pLinkPath = NULL; + } + + nNumMP3s++; + + OutputDebugString(fd.cFileName); + + if ( f ) fprintf(f, " - OK\n"); + } + else + { + strcat(filepath, " - NOT A VALID MP3"); + OutputDebugString(filepath); + + if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n"); + } + } + } + } + + if ( f ) + { + fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s); + fclose(f); + } + + FindClose(hFind); +} + +static void +_DeleteMP3Entries(void) +{ + tMP3Entry *e = _pMP3List; + + while ( e != NULL ) + { + tMP3Entry *next = e->pNext; + + if ( next == NULL ) + next = NULL; + + if ( e->pLinkPath != NULL ) + { +#ifndef FIX_BUGS + delete e->pLinkPath; // BUG: should be delete [] +#else + delete[] e->pLinkPath; +#endif + e->pLinkPath = NULL; + } + + delete e; + + if ( next ) + e = next; + else + e = NULL; + + nNumMP3s--; + } + + + if ( nNumMP3s != 0 ) + { + OutputDebugString("Not all MP3 entries were deleted"); + nNumMP3s = 0; + } + + _pMP3List = NULL; +} + +static tMP3Entry * +_GetMP3EntryByIndex(uint32 idx) +{ + uint32 n = ( idx < nNumMP3s ) ? idx : 0; + + if ( _pMP3List != NULL ) + { + tMP3Entry *e = _pMP3List; + + for ( uint32 i = 0; i < n; i++ ) + e = e->pNext; + + return e; + + } + + return NULL; +} + +static inline bool +_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry) +{ + _CurMP3Index = 0; + + for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext ) + { + if ( *pPosition >= (*pEntry)->nTrackStreamPos + && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos ) + { + *pPosition -= (*pEntry)->nTrackStreamPos; + _CurMP3Pos = *pPosition; + + return true; + } + + _CurMP3Index++; + } + + *pPosition = 0; + *pEntry = _pMP3List; + _CurMP3Pos = 0; + _CurMP3Index = 0; + + return false; +} + +bool +cSampleManager::IsMP3RadioChannelAvailable(void) +{ + return nNumMP3s != 0; +} + +void +cSampleManager::ReleaseDigitalHandle(void) +{ + if ( DIG ) + { + prevprovider = curprovider; + release_existing(); + curprovider = -1; + AIL_digital_handle_release(DIG); + } +} + +void +cSampleManager::ReacquireDigitalHandle(void) +{ + if ( DIG ) + { + AIL_digital_handle_reacquire(DIG); + if ( prevprovider != -1 ) + set_new_provider(prevprovider); + } +} + +bool +cSampleManager::Initialise(void) +{ + TRACE("start"); + + if ( _bSampmanInitialised ) + return true; + + { + for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ ) + { + m_aSamples[i].nOffset = 0; + m_aSamples[i].nSize = 0; + m_aSamples[i].nFrequency = 22050; + 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; + } + + // miles + TRACE("MILES"); + { + curprovider = -1; + prevprovider = -1; + + _usingMilesFast2D = false; + usingEAX=0; + usingEAX3=0; + + _fEffectsLevel = 0.0f; + + _maxSamples = 0; + + opened_provider = NULL; + DIG = NULL; + + for ( int32 i = 0; i < MAXCHANNELS; i++ ) + opened_samples[i] = NULL; + } + + // banks + TRACE("banks"); + { + fpSampleDescHandle = NULL; + fpSampleDataHandle = NULL; + + _nSampleDataEndOffset = 0; + + for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ ) + { + bSampleBankLoaded[i] = false; + nSampleBankDiscStartOffset[i] = 0; + nSampleBankSize[i] = 0; + nSampleBankMemoryStartAddress[i] = 0; + } + } + + // pedsfx + TRACE("pedsfx"); + { + for ( int32 i = 0; i < MAX_PEDSFX; i++ ) + { + nPedSlotSfx[i] = NO_SAMPLE; + nPedSlotSfxAddr[i] = 0; + } + + nCurrentPedSlot = 0; + } + + // channel volume + TRACE("vol"); + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + nChannelVolume[i] = 0; + } + + TRACE("mss"); + { + AIL_set_redist_directory( "mss" ); + + AIL_startup(); + + AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS); + + DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0); + if ( DIG == NULL ) + { + OutputDebugString(AIL_last_error()); + Terminate(); + return false; + } + + add_providers(); + + if ( !InitialiseSampleBanks() ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]); + if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] ) + { + Terminate(); + return false; + } + + nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX); + + } + + TRACE("cdrom"); + + S32 tatalms; + char filepath[MAX_PATH]; + + { + m_bInitialised = false; + + while (true) + { + int32 drive = 'C'; + + do + { + char latter[2]; + + latter[0] = drive; + latter[1] = '\0'; + + strcpy(m_szCDRomRootPath, latter); + strcat(m_szCDRomRootPath, ":\\"); + + if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM ) + { + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[0]); + + FILE *f = fopen(filepath, "rb"); + + if ( f ) + { + fclose(f); + + bool bFileNotFound = false; + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + nStreamLength[i] = tatalms; + } + else + { + bFileNotFound = true; + break; + } + } + + if ( !bFileNotFound ) + { + m_bInitialised = true; + break; + } + else + { + m_bInitialised = false; + continue; + } + } + } + + } while ( ++drive <= 'Z' ); + + if ( !m_bInitialised ) + { +#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) + FrontEndMenuManager.WaitForUserCD(); + if ( FrontEndMenuManager.m_bQuitGameNoCD ) + { + Terminate(); + return false; + } + continue; +#else + m_bInitialised = true; +#endif + } + + break; + } + } + +#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) + // hddaudio + /** + Option for user to play audio files directly from hard disk. + Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory. + Grand Theft Auto III still requires the presence of the PLAY disc when started. + This may give better performance on some machines (though worse on others). + **/ + TRACE("hddaudio 1.1 patch"); + { + int32 streamLength[TOTAL_STREAMED_SOUNDS]; + + bool bFileNotFound = false; + char rootpath[MAX_PATH]; + + strcpy(_aHDDPath, m_szCDRomRootPath); + rootpath[0] = '\0'; + + FILE *f = fopen(StreamedNameTable[0], "rb"); + + if ( f ) + { + fclose(f); + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + { + strcpy(filepath, rootpath); + strcat(filepath, StreamedNameTable[i]); + + mp3Stream[0] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[0] ) + { + AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL); + + AIL_close_stream(mp3Stream[0]); + mp3Stream[0] = NULL; + + streamLength[i] = tatalms; + } + else + { + bFileNotFound = true; + break; + } + } + + } + else + bFileNotFound = true; + + if ( !bFileNotFound ) + { + strcpy(m_szCDRomRootPath, rootpath); + + for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) + nStreamLength[i] = streamLength[i]; + + _bUseHDDAudio = true; + } + else + _bUseHDDAudio = false; + } +#endif + + TRACE("stream"); + { + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + mp3Stream [i] = NULL; + nStreamPan [i] = 63; + nStreamVolume[i] = 100; + } + } + + for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) + { + opened_2dsamples[i] = AIL_allocate_sample_handle(DIG); + if ( opened_2dsamples[i] ) + { + AIL_init_sample(opened_2dsamples[i]); + AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN); + } + } + + TRACE("providerset"); + { + _bSampmanInitialised = true; + + U32 n = 0; + + while ( n < m_nNumberOfProviders ) + { + if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") ) + { + set_new_provider(n); + break; + } + n++; + } + + if ( n == m_nNumberOfProviders ) + { + Terminate(); + return false; + } + } + + TRACE("bank"); + + LoadSampleBank(SAMPLEBANK_MAIN); + + // mp3 + TRACE("mp3"); + { + nNumMP3s = 0; + + _pMP3List = NULL; + + _FindMP3s(); + + if ( nNumMP3s != 0 ) + { + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0; + + for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext ) + { + e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER]; + nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength; + } + + time_t t = time(NULL); + tm *localtm; + bool bUseRandomTable; + + if ( t == -1 ) + bUseRandomTable = true; + else + { + bUseRandomTable = false; + localtm = localtime(&t); + } + + int32 randval; + if ( bUseRandomTable ) + randval = AudioManager.GetRandomNumber(1); + else + randval = localtm->tm_sec * localtm->tm_min; + + _CurMP3Index = randval % nNumMP3s; + + tMP3Entry *randmp3 = _pMP3List; + for ( int32 i = randval % nNumMP3s; i > 0; --i) + randmp3 = randmp3->pNext; + + if ( bUseRandomTable ) + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + else + { + if ( localtm->tm_sec > 0 ) + { + int32 s = localtm->tm_sec; + _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength; + } + else + _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength; + } + } + else + _CurMP3Pos = 0; + + _bIsMp3Active = false; + } + + TRACE("end"); + + return true; +} + +void +cSampleManager::Terminate(void) +{ + for ( int32 i = 0; i < MAX_STREAMS; i++ ) + { + if ( mp3Stream[i] ) + { + AIL_pause_stream(mp3Stream[i], 1); + AIL_close_stream(mp3Stream[i]); + mp3Stream[i] = NULL; + } + } + + for ( int32 i = 0; i < MAX2DCHANNELS; i++ ) + { + if ( opened_2dsamples[i] ) + { + AIL_release_sample_handle(opened_2dsamples[i]); + opened_2dsamples[i] = NULL; + } + } + + release_existing(); + + _DeleteMP3Entries(); + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 ) + { + AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]); + nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0; + } + + if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 ) + { + AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]); + nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0; + } + + if ( DIG ) + { + AIL_close_digital_driver(DIG); + DIG = NULL; + } + + AIL_shutdown(); + + _bSampmanInitialised = false; +} + +bool +cSampleManager::CheckForAnAudioFileOnCD(void) +{ +#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) + char filepath[MAX_PATH]; + +#if defined(GTA3_1_1_PATCH) + if (_bUseHDDAudio) + strcpy(filepath, _aHDDPath); + else + strcpy(filepath, m_szCDRomRootPath); +#else + strcpy(filepath, m_szCDRomRootPath); +#endif // #if defined(GTA3_1_1_PATCH) + + strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]); + + FILE *f = fopen(filepath, "rb"); + + if ( f ) + { + fclose(f); + + return true; + } + + return false; + +#else + return true; +#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK) +} + +char +cSampleManager::GetCDAudioDriveLetter(void) +{ +#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK) + if (_bUseHDDAudio) + { + if ( strlen(_aHDDPath) != 0 ) + return _aHDDPath[0]; + else + return '\0'; + } + else + { + if ( strlen(m_szCDRomRootPath) != 0 ) + return m_szCDRomRootPath[0]; + else + return '\0'; + } +#else + if ( strlen(m_szCDRomRootPath) != 0 ) + return m_szCDRomRootPath[0]; + else + return '\0'; +#endif +} + +void +cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ? +{ + if ( _bSampmanInitialised ) + { + for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ ) + { + if ( i < MAXCHANNELS ) + { + if ( opened_samples[i] && GetChannelUsedFlag(i) ) + { + if ( nChannelVolume[i] ) + { + AIL_set_3D_sample_volume(opened_samples[i], + m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14); + } + } + } + else + { + if ( opened_2dsamples[i - MAXCHANNELS] ) + { + if ( GetChannelUsedFlag(i - MAXCHANNELS) ) + { + if ( nChannelVolume[i - MAXCHANNELS] ) + { + AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS], + m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * 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) +{ + 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) +{ + bSampleBankLoaded[nBank] = false; +} + +bool +cSampleManager::IsSampleBankLoaded(uint8 nBank) +{ + return bSampleBankLoaded[nBank]; +} + +bool +cSampleManager::IsPedCommentLoaded(uint32 nComment) +{ + 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) +{ + 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; + + nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot; + nPedSlotSfx [nCurrentPedSlot] = nComment; + + 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) +{ + return m_aSamples[nSample].nFrequency; +} + +int32 +cSampleManager::GetSampleLoopStartOffset(uint32 nSample) +{ + return m_aSamples[nSample].nLoopStart; +} + +int32 +cSampleManager::GetSampleLoopEndOffset(uint32 nSample) +{ + return m_aSamples[nSample].nLoopEnd; +} + +uint32 +cSampleManager::GetSampleLength(uint32 nSample) +{ + return m_aSamples[nSample].nSize >> 1; +} + +bool +cSampleManager::UpdateReverb(void) +{ + if ( !usingEAX ) + 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); + + float fRatio; + + if ( normy == 0.0f ) + { + if ( normx == 0.0f ) + { + if ( normz == 0.0f ) + fRatio = 0.3f; + else + fRatio = 0.5f; + } + else + { + fRatio = 0.3f; + } + } + else + { + if ( normx == 0.0f ) + { + if ( normz == 0.0f ) + fRatio = 0.3f; + else + fRatio = 0.5f; + } + else + { + if ( normz == 0.0f ) + fRatio = 0.3f; + else + fRatio = (normy+normx+normz) / 3.0f; + } + } + + fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f); + + if ( fRatio == _fPrevEaxRatioDestination ) + return false; + + if ( usingEAX3 ) + { + if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) ) + { + AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params); + _fEffectsLevel = 1.0f - fRatio * 0.5f; + } + } + else + { + if ( _usingMilesFast2D ) + _fEffectsLevel = (1.0f - fRatio) * 0.4f; + else + _fEffectsLevel = (1.0f - fRatio) * 0.7f; + } + + _fPrevEaxRatioDestination = fRatio; + + return true; +} + +void +cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( usingEAX ) + { + if ( nReverbFlag != 0 ) + { + if ( !b2d ) + AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel); + } + else + { + if ( !b2d ) + AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f); + } + } +} + +bool +cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + int32 addr; + + if ( nSfx < SAMPLEBANK_MAX ) + { + if ( !IsSampleBankLoaded(nBank) ) + return false; + + addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; + } + else + { + if ( !IsPedCommentLoaded(nSfx) ) + return false; + + int32 slot = _GetPedCommentSlot(nSfx); + + addr = nPedSlotSfxAddr[slot]; + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + { + AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize); + return true; + } + else + return false; + } + else + { + AILSOUNDINFO info; + + info.format = WAVE_FORMAT_PCM; + info.data_ptr = (void *)addr; + info.channels = 1; + info.data_len = m_aSamples[nSfx].nSize; + info.rate = m_aSamples[nSfx].nFrequency; + info.bits = 16; + + if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 ) + { + OutputDebugString(AIL_last_error()); + return false; + } + + return true; + } +} + +void +cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) +{ + 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; + } + + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14); + +} + +void +cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) +{ + if ( opened_samples[nChannel] ) + AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ); +} + +void +cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) +{ + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin); +} + +void +cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) +{ + uint32 vol = nVolume; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + switch ( nChannel ) + { + case CHANNEL2D: + { + 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; + } + + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + { + AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS], + m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + } + + break; + } + } +} + +void +cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) +{ + switch ( nChannel ) + { + case CHANNEL2D: + { +#ifndef FIX_BUGS + if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG +#else + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) +#endif + AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan); + + break; + } + } +} + +void +cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq); + } +} + +void +cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd); + } +} + +void +cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount); + } + else + { + if ( opened_samples[nChannel] ) + AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount); + } +} + +bool +cSampleManager::GetChannelUsedFlag(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING; + else + return false; + } + else + { + if ( opened_samples[nChannel] ) + return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING; + else + return false; + } + +} + +void +cSampleManager::StartChannel(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]); + } + else + { + if ( opened_samples[nChannel] ) + AIL_start_3D_sample(opened_samples[nChannel]); + } +} + +void +cSampleManager::StopChannel(uint32 nChannel) +{ + bool b2d = false; + + switch ( nChannel ) + { + case CHANNEL2D: + { + b2d = true; + break; + } + } + + if ( b2d ) + { + if ( opened_2dsamples[nChannel - MAXCHANNELS] ) + AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]); + } + else + { + if ( opened_samples[nChannel] ) + { + if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING ) + AIL_end_3D_sample(opened_samples[nChannel]); + } + } +} + +void +cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + AIL_close_stream(mp3Stream[nStream]); + } + + char filepath[MAX_PATH]; + + strcpy(filepath, m_szCDRomRootPath); + strcat(filepath, StreamedNameTable[nFile]); + + mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0); + + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_service_stream(mp3Stream[nStream], 1); + } + else + OutputDebugString(AIL_last_error()); + } + } +} + +void +cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0); + } +} + +void +cSampleManager::StartPreloadedStreamedFile(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + AIL_start_stream(mp3Stream[nStream]); + } +} + +bool +cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) +{ + uint32 position = nPos; + char filename[MAX_PATH]; + + if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + AIL_close_stream(mp3Stream[nStream]); + } + + if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER ) + { + uint32 i = 0; + do { + if(i != 0 || _bIsMp3Active) { + if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0; + + _CurMP3Pos = 0; + + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if(mp3) { + mp3 = _pMP3List; + if(mp3 == NULL) { + _bIsMp3Active = false; + nFile = 0; + strcpy(filename, m_szCDRomRootPath); + strcat(filename, StreamedNameTable[nFile]); + + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count( + mp3Stream[nStream], 1); + AIL_set_stream_ms_position( + mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], + 0); + return true; + } + + return false; + } + } + + if(mp3->pLinkPath != NULL) + mp3Stream[nStream] = + AIL_open_stream(DIG, mp3->pLinkPath, 0); + else { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, mp3->aFilename); + + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + } + + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], 0); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + + _bIsMp3Active = false; + continue; + } + if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] ) + position = 0; + + tMP3Entry *e; + if ( !_GetMP3PosFromStreamPos(&position, &e) ) + { + if ( e == NULL ) + { + nFile = 0; + strcpy(filename, m_szCDRomRootPath); + strcat(filename, StreamedNameTable[nFile]); + mp3Stream[nStream] = + AIL_open_stream(DIG, filename, 0); + if(mp3Stream[nStream]) { + AIL_set_stream_loop_count( + mp3Stream[nStream], 1); + AIL_set_stream_ms_position( + mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + + return false; + } + } + + if ( e->pLinkPath != NULL ) + mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0); + else + { + strcpy(filename, _mp3DirectoryPath); + strcat(filename, e->aFilename); + + mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); + } + + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + + _bIsMp3Active = true; + + return true; + } + + _bIsMp3Active = false; + + } while(++i < nNumMP3s); + + position = 0; + nFile = 0; + } + + strcpy(filename, m_szCDRomRootPath); + strcat(filename, StreamedNameTable[nFile]); + + mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0); + if ( mp3Stream[nStream] ) + { + AIL_set_stream_loop_count(mp3Stream[nStream], 1); + AIL_set_stream_ms_position(mp3Stream[nStream], position); + AIL_pause_stream(mp3Stream[nStream], 0); + return true; + } + } + + return false; +} + +void +cSampleManager::StopStreamedFile(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + AIL_pause_stream(mp3Stream[nStream], 1); + + AIL_close_stream(mp3Stream[nStream]); + mp3Stream[nStream] = NULL; + + if ( nStream == 0 ) + _bIsMp3Active = false; + } + } +} + +int32 +cSampleManager::GetStreamedFilePosition(uint8 nStream) +{ + S32 currentms; + + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + if ( _bIsMp3Active ) + { + tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index); + + if ( mp3 != NULL ) + { + AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); + return currentms + mp3->nTrackStreamPos; + } + else + return 0; + } + else + { + AIL_stream_ms_position(mp3Stream[nStream], NULL, ¤tms); + return currentms; + } + } + } + + return 0; +} + +void +cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream) +{ + uint8 vol = nVolume; + + if ( m_bInitialised ) + { + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + if ( vol > MAX_VOLUME ) vol = MAX_VOLUME; + + nStreamVolume[nStream] = vol; + nStreamPan[nStream] = nPan; + + if ( mp3Stream[nStream] ) + { + if ( nEffectFlag ) + AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); + else + AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14); + + AIL_set_stream_pan(mp3Stream[nStream], nPan); + } + } +} + +int32 +cSampleManager::GetStreamedFileLength(uint8 nStream) +{ + if ( m_bInitialised ) + return nStreamLength[nStream]; + + return 0; +} + +bool +cSampleManager::IsStreamPlaying(uint8 nStream) +{ + if ( m_bInitialised ) + { + if ( mp3Stream[nStream] ) + { + if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING ) + return true; + else + return false; + } + } + + return false; +} + +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); + _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/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp new file mode 100644 index 00000000..3eb296ae --- /dev/null +++ b/src/audio/sampman_oal.cpp @@ -0,0 +1,1372 @@ +#include "common.h" +//#define JUICY_OAL + +#ifdef AUDIO_OAL +#include "sampman.h" + +#include +#include + +#include "eax.h" +#include "eax-util.h" + +#include +#include +#include +#include +#include + +#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 max channals +//todo queue +//todo loop count +//todo mp3/wav stream +//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 +{ + std::string id; + 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; +}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 ) + { + providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(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 ) + { + providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(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 ) + { + providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(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;jGetDefaultDevice(); + 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++ ) + { + alDeleteSources(1, &ALStreamSources[i]); + alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); + } + + alDeleteBuffers(MAX_PEDSFX, pedBuffers); + + for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) + { + if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) ) + alDeleteBuffers(1, &ALBuffers[i].buffer); + + ALBuffers[i].timer = 0; + } + + 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.c_str()); + 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]); + } + + for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) + { + ALBuffers[i].buffer = 0; + ALBuffers[i].timer = 0; + } + + 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; + } + + { + 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); + } + + { + 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] = 3600000; + } + + { + _bSampmanInitialised = true; + + if ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders ) + { + set_new_provider(defaultProvider); + } + else + { + Terminate(); + return false; + } + } + + 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++ ) + { + if ( ALBuffers[i].timer > 0 ) + { + ALBuffers[i].timer -= ALuint(CTimer::GetTimeStepInMilliseconds()); + + 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].timer = 0; + else + ALBuffers[i].timer = 10000; + } + } + } + } +} + +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 >> 1; +} + +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].timer == 0 ) + { + ALuint buf; + + alGenBuffers(1, &buf); + alBufferData(buf, AL_FORMAT_MONO16, (void *)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency); + ALBuffers[nSfx].buffer = buf; + ALBuffers[nSfx].timer = 10000; + } + + 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] >>= 2; + } + + // 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] >>= 2; + } + + 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->GetLength(); + if ( stream->Setup() ) + { + if ( nPos != 0 ) + stream->SetPos(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->GetPos(); + } + + 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; + + 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 8633d222..8ab12e3f 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/config.h b/src/core/config.h index 163af701..23fe9993 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -193,7 +193,8 @@ enum Config { #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) #define USE_TXD_CDIMAGE // generate and load textures from txd.img //#define USE_TEXTURE_POOL -//#define OPENAL +#define AUDIO_OAL +//#define AUDIO_MSS // Particle //#define PC_PARTICLE diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index 288788c0..20e5c49c 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -1773,13 +1773,12 @@ WinMain(HINSTANCE instance, StaticPatcher::Apply(); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE); -/* + // TODO: make this an option somewhere AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); -*/ /* * Initialize the platform independent data. -- cgit v1.2.3 From 0abd0c659b39805a457896427980414cdc552ff8 Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Mon, 4 May 2020 21:06:14 +0300 Subject: openal-soft added --- src/audio/oal/oal_utils.cpp | 107 +++++++++++++++++++++----------------------- src/audio/sampman_oal.cpp | 10 ++--- src/core/config.h | 4 +- src/skel/win/win.cpp | 3 +- 4 files changed, 59 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp index a2df61c1..4119672f 100644 --- a/src/audio/oal/oal_utils.cpp +++ b/src/audio/oal/oal_utils.cpp @@ -39,26 +39,20 @@ LPALGETFILTERFV alGetFilterfv; void EFXInit() { - if (alIsExtensionPresent((ALchar*)"EAX3.0")) - DEV("\nBIG EAX IN TOWN\n"); - else - DEV("\nNO EAX\n"); - - - /* Define a macro to help load the function pointers. */ + /* Define 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(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); @@ -70,22 +64,21 @@ void EFXInit() 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); + + 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); @@ -103,7 +96,7 @@ 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) +static inline float clampF(float val, float minval, float maxval) { if(val >= maxval) return maxval; if(val <= minval) return minval; @@ -113,35 +106,35 @@ static inline FLOAT clampF(FLOAT val, FLOAT minval, FLOAT maxval) 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); + 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)); diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index 3eb296ae..a73bc2bd 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -26,11 +26,11 @@ #include "Frontend.h" #include "Timer.h" -//todo max channals -//todo queue -//todo loop count -//todo mp3/wav stream -//todo mp3 player +//TODO: fix eax3 reverb +//TODO: max channals +//TODO: loop count +//TODO: mp3/wav stream +//TODO: mp3 player #pragma comment( lib, "OpenAL32.lib" ) diff --git a/src/core/config.h b/src/core/config.h index 23fe9993..6896a7ba 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -193,8 +193,8 @@ enum Config { #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) #define USE_TXD_CDIMAGE // generate and load textures from txd.img //#define USE_TEXTURE_POOL -#define AUDIO_OAL -//#define AUDIO_MSS +//#define AUDIO_OAL +#define AUDIO_MSS // Particle //#define PC_PARTICLE diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index 20e5c49c..288788c0 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -1773,12 +1773,13 @@ WinMain(HINSTANCE instance, StaticPatcher::Apply(); SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE); - +/* // TODO: make this an option somewhere AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); +*/ /* * Initialize the platform independent data. -- cgit v1.2.3 From 6382b6d2fc467fa188793433563a1d20c80b9c9e Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Mon, 4 May 2020 21:32:42 +0300 Subject: fix typo --- src/audio/DMAudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index 8681f345..f1b9707b 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -119,7 +119,7 @@ int8 cDMAudio::AutoDetect3DProviders(void) if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") ) return i; #elif defined(AUDIO_OAL) - if ( !strcmp(providername, "OPEANAL SOFT") ) + if ( !strcmp(providername, "OPENAL SOFT") ) return i; #endif } -- cgit v1.2.3 From 73c809f616b15cd1eb41c5642ee1242d18275e0d Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Mon, 4 May 2020 22:02:54 +0300 Subject: bb std::string --- src/audio/sampman_oal.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index a73bc2bd..6ae1bf79 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -54,7 +54,7 @@ ALuint ALEffect = AL_EFFECT_NULL; ALuint ALEffectSlot = AL_EFFECTSLOT_NULL; struct { - std::string id; + char id[256]; char name[256]; int sources; }providers[MAXPROVIDERS]; @@ -137,7 +137,7 @@ add_providers() { if ( n < MAXPROVIDERS ) { - providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(pDeviceList->GetDeviceName(i))); + 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); @@ -152,7 +152,7 @@ add_providers() { if ( n < MAXPROVIDERS ) { - providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(pDeviceList->GetDeviceName(i))); + 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); @@ -162,7 +162,7 @@ add_providers() if ( n < MAXPROVIDERS ) { - providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(pDeviceList->GetDeviceName(i))); + 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); @@ -263,7 +263,7 @@ set_new_provider(int index) ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0}; - ALDevice = alcOpenDevice(providers[index].id.c_str()); + ALDevice = alcOpenDevice(providers[index].id); ASSERT(ALDevice != NULL); ALContext = alcCreateContext(ALDevice, attr); -- cgit v1.2.3 From 12a3499ca365756a77958d616423aca39a23234b Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Thu, 7 May 2020 09:26:16 +0300 Subject: oal wav/mp3 stream update --- src/audio/oal/channel.cpp | 59 +++--- src/audio/oal/channel.h | 4 +- src/audio/oal/stream.cpp | 476 ++++++++++++++++++++++++++++++++++++++++++---- src/audio/oal/stream.h | 89 +++++++-- src/audio/sampman_oal.cpp | 71 ++++--- src/core/common.h | 2 + src/core/re3.cpp | 14 ++ 7 files changed, 608 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp index d8b50161..7742a06a 100644 --- a/src/audio/oal/channel.cpp +++ b/src/audio/oal/channel.cpp @@ -1,20 +1,21 @@ #include "channel.h" #ifdef AUDIO_OAL +#include "common.h" #include "sampman.h" extern bool IsFXSupported(); CChannel::CChannel() { - alChannel = AL_NONE; + alSource = AL_NONE; alFilter = AL_FILTER_NULL; SetDefault(); } void CChannel::SetDefault() { - Buffer = AL_NONE; + alBuffer = AL_NONE; Pitch = 1.0f; Gain = 1.0f; @@ -37,17 +38,17 @@ void CChannel::Reset() void CChannel::Init(bool Is2D) { ASSERT(!HasSource()); - alGenSources(1, &alChannel); + alGenSources(1, &alSource); if ( HasSource() ) { - alSourcei(alChannel, AL_SOURCE_RELATIVE, AL_TRUE); + alSourcei(alSource, AL_SOURCE_RELATIVE, AL_TRUE); if ( IsFXSupported() ) - alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); if ( Is2D ) { - alSource3f(alChannel, AL_POSITION, 0.0f, 0.0f, 0.0f); - alSourcef (alChannel, AL_GAIN, 1.0f); + alSource3f(alSource, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef (alSource, AL_GAIN, 1.0f); } else { @@ -64,15 +65,15 @@ void CChannel::Term() { if ( IsFXSupported() ) { - alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); + alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); if(alFilter != AL_FILTER_NULL) alDeleteFilters(1,&alFilter); } - alDeleteSources(1, &alChannel); + alDeleteSources(1, &alSource); } - alChannel = AL_NONE; + alSource = AL_NONE; alFilter = AL_FILTER_NULL; } @@ -81,22 +82,22 @@ void CChannel::Start() if ( !HasSource() ) return; if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 ) - alBufferiv(Buffer, AL_LOOP_POINTS_SOFT, LoopPoints); - alSourcei (alChannel, AL_BUFFER, Buffer); - alSourcePlay(alChannel); + alBufferiv(alBuffer, AL_LOOP_POINTS_SOFT, LoopPoints); + alSourcei (alSource, AL_BUFFER, alBuffer); + alSourcePlay(alSource); } void CChannel::Stop() { if ( HasSource() ) - alSourceStop(alChannel); + alSourceStop(alSource); Reset(); } bool CChannel::HasSource() { - return alChannel != AL_NONE; + return alSource != AL_NONE; } bool CChannel::IsUsed() @@ -104,7 +105,7 @@ bool CChannel::IsUsed() if ( HasSource() ) { ALint sourceState; - alGetSourcei(alChannel, AL_SOURCE_STATE, &sourceState); + alGetSourcei(alSource, AL_SOURCE_STATE, &sourceState); return sourceState == AL_PLAYING; } return false; @@ -113,13 +114,13 @@ bool CChannel::IsUsed() void CChannel::SetPitch(float pitch) { if ( !HasSource() ) return; - alSourcef(alChannel, AL_PITCH, pitch); + alSourcef(alSource, AL_PITCH, pitch); } void CChannel::SetGain(float gain) { if ( !HasSource() ) return; - alSourcef(alChannel, AL_GAIN, gain); + alSourcef(alSource, AL_GAIN, gain); } void CChannel::SetVolume(int32 vol) @@ -145,7 +146,7 @@ void CChannel::SetCurrentFreq(uint32 freq) void CChannel::SetLoopCount(int32 loopCount) // fake. TODO: { if ( !HasSource() ) return; - alSourcei(alChannel, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE); + alSourcei(alSource, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE); } void CChannel::SetLoopPoints(ALint start, ALint end) @@ -157,33 +158,33 @@ void CChannel::SetLoopPoints(ALint start, ALint end) void CChannel::SetPosition(float x, float y, float z) { if ( !HasSource() ) return; - alSource3f(alChannel, AL_POSITION, x, y, z); + alSource3f(alSource, AL_POSITION, x, y, z); } void CChannel::SetDistances(float max, float min) { if ( !HasSource() ) return; - alSourcef (alChannel, AL_MAX_DISTANCE, max); - alSourcef (alChannel, AL_REFERENCE_DISTANCE, min); - alSourcef (alChannel, AL_MAX_GAIN, 1.0f); - alSourcef (alChannel, AL_ROLLOFF_FACTOR, 1.0f); + 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, sqrtf(1.0f-SQR((pan-63)/64.0f))); + SetPosition((pan-63)/64.0f, 0.0f, Sqrt(1.0f-SQR((pan-63)/64.0f))); } void CChannel::SetBuffer(ALuint buffer) { - Buffer = buffer; + alBuffer = buffer; } void CChannel::ClearBuffer() { if ( !HasSource() ) return; SetBuffer(AL_NONE); - alSourcei(alChannel, AL_BUFFER, AL_NONE); + alSourcei(alSource, AL_BUFFER, AL_NONE); } void CChannel::SetReverbMix(ALuint slot, float mix) @@ -194,7 +195,7 @@ void CChannel::SetReverbMix(ALuint slot, float mix) Mix = mix; EAX3_SetReverbMix(alFilter, mix); - alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); + alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); } void CChannel::UpdateReverb(ALuint slot) @@ -203,7 +204,7 @@ void CChannel::UpdateReverb(ALuint slot) if ( !HasSource() ) return; if ( alFilter == AL_FILTER_NULL ) return; EAX3_SetReverbMix(alFilter, Mix); - alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter); + 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 index d9ffea22..4dd09ca1 100644 --- a/src/audio/oal/channel.h +++ b/src/audio/oal/channel.h @@ -10,9 +10,9 @@ class CChannel { - ALuint alChannel; + ALuint alSource; ALuint alFilter; - ALuint Buffer; + ALuint alBuffer; float Pitch, Gain; float Mix; int32 Frequency; diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp index a65c9794..9bca0546 100644 --- a/src/audio/oal/stream.cpp +++ b/src/audio/oal/stream.cpp @@ -1,48 +1,223 @@ #include "stream.h" -#include "common.h" #ifdef AUDIO_OAL +#include "common.h" +#include "sampman.h" + +typedef long ssize_t; + +#include +#include + +#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(); + mpg123_init(); } void CStream::Terminate() { - //mpg123_exit(); + mpg123_exit(); } CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) : m_alSource(source), m_alBuffers(buffers), - m_nBitRate(0), - m_nFormat(0), - m_nFreq(0), - m_nLength(0), - m_nLengthMS(0), - m_nBufferSize(0), - m_pBuffer(NULL), - m_bIsOpened(false), - m_bPaused(true) + 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 ( true ) - { - m_nBitRate = (wBitsPerSample * nChannels * wfex.nSamplesPerSec)/1000; - m_nLength = ulDataSize; - m_nLengthMS = m_nLength*8 / m_nBitRate; - m_nBufferSize = nAvgBytesPerSec >> 2; - m_nBufferSize -= (m_nLength % wfex.nBlockAlign); - m_pBuffer = malloc(m_nBufferSize); - m_bIsOpened = true; + 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() @@ -51,68 +226,295 @@ CStream::~CStream() } void CStream::Delete() -{ +{ + Stop(); + ClearBuffers(); + + if ( m_pSoundFile ) + { + delete m_pSoundFile; + m_pSoundFile = nil; + } + if ( m_pBuffer ) { free(m_pBuffer); - m_pBuffer = NULL; + m_pBuffer = nil; } } +bool CStream::HasSource() +{ + return m_alSource != AL_NONE; +} + bool CStream::IsOpened() { - return m_bIsOpened; + 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::SetPos(uint32 nPos) +void CStream::SetPosMS(uint32 nPos) { + if ( !m_pSoundFile->IsOpened() ) return; + m_pSoundFile->Seek(nPos); + ClearBuffers(); } -uint32 CStream::GetPos() +uint32 CStream::GetPosMS() { - return 0; + 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::GetLength() +uint32 CStream::GetLengthMS() { - return m_nLengthMS; + if ( !m_pSoundFile->IsOpened() ) return 0; + return m_pSoundFile->GetLength(); } -bool CStream::Setup() +bool CStream::FillBuffer(ALuint alBuffer) { - if ( !IsOpened() ) + 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 index 666d42e0..f1e5f458 100644 --- a/src/audio/oal/stream.h +++ b/src/audio/oal/stream.h @@ -4,8 +4,56 @@ #ifdef AUDIO_OAL #include -#define NUM_STREAMBUFFERS 5 -#define STREAMBUFFER_SIZE 0x4000 +#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 { @@ -13,30 +61,34 @@ class CStream ALuint &m_alSource; ALuint (&m_alBuffers)[NUM_STREAMBUFFERS]; - bool m_bIsOpened; bool m_bPaused; - - uint32 m_nLength; - uint32 m_nLengthMS; - uint32 m_nBitRate; - - unsigned long m_nFormat; - unsigned long m_nFreq; + bool m_bActive; - uint32 m_nBufferSize; void *m_pBuffer; - ALint iTotalBuffersProcessed; + 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(); @@ -44,14 +96,17 @@ public: void SetPause (bool bPause); void SetVolume(uint32 nVol); void SetPan (uint8 nPan); - void SetPos (uint32 nPos); - - uint32 GetPos(); - uint32 GetLength(); + 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/sampman_oal.cpp b/src/audio/sampman_oal.cpp index 6ae1bf79..ccddaa73 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -29,7 +29,6 @@ //TODO: fix eax3 reverb //TODO: max channals //TODO: loop count -//TODO: mp3/wav stream //TODO: mp3 player #pragma comment( lib, "OpenAL32.lib" ) @@ -179,9 +178,9 @@ add_providers() defaultProvider = pDeviceList->GetDefaultDevice(); if ( defaultProvider > MAXPROVIDERS ) defaultProvider = 0; - - delete pDeviceList; } + + delete pDeviceList; } static void @@ -211,6 +210,10 @@ release_existing() 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]); } @@ -298,6 +301,10 @@ set_new_provider(int index) { 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++ ) @@ -523,6 +530,18 @@ cSampleManager::Initialise(void) 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(); @@ -545,17 +564,6 @@ cSampleManager::Initialise(void) ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL); } - { - 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] = 3600000; - } { _bSampmanInitialised = true; @@ -571,6 +579,25 @@ cSampleManager::Initialise(void) } } + { + + 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; @@ -653,7 +680,7 @@ cSampleManager::UpdateEffectsVolume(void) if ( GetChannelUsedFlag(i) ) { if ( nChannelVolume[i] != 0 ) - aChannel[i].SetVolume(m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14); + aChannel[i].SetVolume(m_nEffectsFadeVolume*nChannelVolume[i]*m_nEffectsVolume >> 14); } } } @@ -853,7 +880,7 @@ uint32 cSampleManager::GetSampleLength(uint32 nSample) { ASSERT( nSample < TOTAL_AUDIO_SAMPLES ); - return m_aSamples[nSample].nSize >> 1; + return m_aSamples[nSample].nSize / sizeof(uint16); } bool cSampleManager::UpdateReverb(void) @@ -1018,7 +1045,7 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) { - nChannelVolume[nChannel] >>= 2; + nChannelVolume[nChannel] = vol / 4; } // no idea, does this one looks like a bug or it's SetChannelVolume ? @@ -1060,7 +1087,7 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD ) { - nChannelVolume[nChannel] >>= 2; + nChannelVolume[nChannel] = vol / 4; } aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14); @@ -1209,11 +1236,11 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream) if ( stream->IsOpened() ) { - nStreamLength[nFile] = stream->GetLength(); + nStreamLength[nFile] = stream->GetLengthMS(); if ( stream->Setup() ) { if ( nPos != 0 ) - stream->SetPos(nPos); + stream->SetPosMS(nPos); stream->Start(); } @@ -1253,7 +1280,7 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream) if ( stream ) { - return stream->GetPos(); + return stream->GetPosMS(); } return 0; @@ -1270,7 +1297,7 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect if ( nPan > MAX_VOLUME ) nPan = MAX_VOLUME; - nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume; + nStreamVolume[nStream] = nVolume; nStreamPan [nStream] = nPan; CStream *stream = aStream[nStream]; diff --git a/src/core/common.h b/src/core/common.h index 18f4715c..66a3ad81 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -209,6 +209,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(); @@ -216,6 +217,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/re3.cpp b/src/core/re3.cpp index 2a9cbc77..b7eb6480 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -456,6 +456,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 -- cgit v1.2.3 From 875c77e8b15c5014ee356c8413273c509daa5bda Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Thu, 7 May 2020 10:13:59 +0300 Subject: oal update --- src/audio/sampman_oal.cpp | 59 +++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index ccddaa73..bbaeae4c 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -88,6 +88,32 @@ 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; @@ -222,10 +248,7 @@ release_existing() for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) { - if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) ) - alDeleteBuffers(1, &ALBuffers[i].buffer); - - ALBuffers[i].timer = 0; + ALBuffers[i].Term(); } if ( ALContext ) @@ -309,8 +332,7 @@ set_new_provider(int index) for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) { - ALBuffers[i].buffer = 0; - ALBuffers[i].timer = 0; + ALBuffers[i].Init(); } alGenBuffers(MAX_PEDSFX, pedBuffers); @@ -640,23 +662,7 @@ cSampleManager::UpdateSoundBuffers(void) { for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ ) { - if ( ALBuffers[i].timer > 0 ) - { - ALBuffers[i].timer -= ALuint(CTimer::GetTimeStepInMilliseconds()); - - 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].timer = 0; - else - ALBuffers[i].timer = 10000; - } - } - } + ALBuffers[i].Update(); } } @@ -981,15 +987,14 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) int32 addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset; - if ( ALBuffers[nSfx].timer == 0 ) + 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].buffer = buf; - ALBuffers[nSfx].timer = 10000; + ALBuffers[nSfx].Set(buf); } + ALBuffers[nSfx].Wait(); buffer = ALBuffers[nSfx].buffer; } -- cgit v1.2.3