|
|
|
@ -1,4 +1,3 @@
|
|
|
|
|
#include "common.h"
|
|
|
|
|
//#define JUICY_OAL
|
|
|
|
|
|
|
|
|
|
#ifdef AUDIO_OAL
|
|
|
|
@ -9,6 +8,10 @@
|
|
|
|
|
#include "eax.h"
|
|
|
|
|
#include "eax-util.h"
|
|
|
|
|
|
|
|
|
|
#define WITHWINDOWS
|
|
|
|
|
#include "common.h"
|
|
|
|
|
#include "crossplatform.h"
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
#include <io.h>
|
|
|
|
|
#include <AL/al.h>
|
|
|
|
@ -27,20 +30,27 @@
|
|
|
|
|
#include "MusicManager.h"
|
|
|
|
|
#include "Frontend.h"
|
|
|
|
|
#include "Timer.h"
|
|
|
|
|
#include "crossplatform.h"
|
|
|
|
|
#ifdef AUDIO_OPUS
|
|
|
|
|
#include <opusfile.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//TODO: fix eax3 reverb
|
|
|
|
|
//TODO: max channals
|
|
|
|
|
//TODO: max channels
|
|
|
|
|
//TODO: loop count
|
|
|
|
|
//TODO: mp3 player
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
#pragma comment( lib, "OpenAL32.lib" )
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// for user MP3s
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
#include <direct.h>
|
|
|
|
|
#include <shobjidl.h>
|
|
|
|
|
#include <shlguid.h>
|
|
|
|
|
#else
|
|
|
|
|
#define _getcwd getcwd
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
cSampleManager SampleManager;
|
|
|
|
|
bool _bSampmanInitialised = false;
|
|
|
|
|
|
|
|
|
@ -128,11 +138,27 @@ struct
|
|
|
|
|
}
|
|
|
|
|
}ALBuffers[SAMPLEBANK_MAX];
|
|
|
|
|
|
|
|
|
|
uint32 nNumMP3s;
|
|
|
|
|
struct tMP3Entry
|
|
|
|
|
{
|
|
|
|
|
char aFilename[MAX_PATH];
|
|
|
|
|
|
|
|
|
|
uint32 nTrackLength;
|
|
|
|
|
uint32 nTrackStreamPos;
|
|
|
|
|
|
|
|
|
|
tMP3Entry* pNext;
|
|
|
|
|
char* pLinkPath;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint32 nNumMP3s;
|
|
|
|
|
tMP3Entry* _pMP3List;
|
|
|
|
|
char _mp3DirectoryPath[MAX_PATH];
|
|
|
|
|
CStream *aStream[MAX_STREAMS];
|
|
|
|
|
uint8 nStreamPan [MAX_STREAMS];
|
|
|
|
|
uint8 nStreamVolume[MAX_STREAMS];
|
|
|
|
|
|
|
|
|
|
uint8 nStreamLoopedFlag[MAX_STREAMS];
|
|
|
|
|
uint32 _CurMP3Index;
|
|
|
|
|
int32 _CurMP3Pos;
|
|
|
|
|
bool _bIsMp3Active;
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
// 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 =
|
|
|
|
@ -451,24 +477,421 @@ int8 cSampleManager::GetCurrent3DProviderIndex(void)
|
|
|
|
|
|
|
|
|
|
int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
|
|
|
|
|
{
|
|
|
|
|
if (nProvider >= m_nNumberOfProviders)
|
|
|
|
|
nProvider = 0;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nProvider = clamp(nProvider, 0, m_nNumberOfProviders - 1);
|
|
|
|
|
|
|
|
|
|
if ( set_new_provider(nProvider) )
|
|
|
|
|
return curprovider;
|
|
|
|
|
else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
|
|
|
|
|
return curprovider;
|
|
|
|
|
else
|
|
|
|
|
return curprovider;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
_ResolveLink(char const *path, char *out)
|
|
|
|
|
{
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
size_t len = strlen(path);
|
|
|
|
|
if (len < 4 || strcmp(&path[len - 4], ".lnk") != 0)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
#else
|
|
|
|
|
struct stat sb;
|
|
|
|
|
|
|
|
|
|
if (lstat(path, &sb) == -1) {
|
|
|
|
|
perror("lstat: ");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (S_ISLNK(sb.st_mode)) {
|
|
|
|
|
char* linkname = (char*)alloca(sb.st_size + 1);
|
|
|
|
|
if (linkname == NULL) {
|
|
|
|
|
fprintf(stderr, "insufficient memory\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (readlink(path, linkname, sb.st_size + 1) < 0) {
|
|
|
|
|
perror("readlink: ");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
linkname[sb.st_size] = '\0';
|
|
|
|
|
strcpy(out, linkname);
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_FindMP3s(void)
|
|
|
|
|
{
|
|
|
|
|
tMP3Entry *pList;
|
|
|
|
|
bool bShortcut;
|
|
|
|
|
bool bInitFirstEntry;
|
|
|
|
|
HANDLE hFind;
|
|
|
|
|
char path[MAX_PATH];
|
|
|
|
|
char filepath[MAX_PATH*2];
|
|
|
|
|
int total_ms;
|
|
|
|
|
WIN32_FIND_DATA fd;
|
|
|
|
|
|
|
|
|
|
if (getcwd(_mp3DirectoryPath, MAX_PATH) == NULL) {
|
|
|
|
|
perror("getcwd: ");
|
|
|
|
|
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 )
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcpy(filepath, _mp3DirectoryPath);
|
|
|
|
|
strcat(filepath, fd.cFileName);
|
|
|
|
|
|
|
|
|
|
size_t filepathlen = strlen(filepath);
|
|
|
|
|
|
|
|
|
|
if ( filepathlen <= 0)
|
|
|
|
|
{
|
|
|
|
|
FindClose(hFind);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( _ResolveLink(filepath, filepath) )
|
|
|
|
|
{
|
|
|
|
|
OutputDebugString("Resolving Link");
|
|
|
|
|
OutputDebugString(filepath);
|
|
|
|
|
bShortcut = true;
|
|
|
|
|
} else
|
|
|
|
|
bShortcut = false;
|
|
|
|
|
|
|
|
|
|
aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]);
|
|
|
|
|
|
|
|
|
|
if (aStream[0] && aStream[0]->IsOpened())
|
|
|
|
|
{
|
|
|
|
|
total_ms = aStream[0]->GetLengthMS();
|
|
|
|
|
delete aStream[0];
|
|
|
|
|
aStream[0] = NULL;
|
|
|
|
|
|
|
|
|
|
OutputDebugString(fd.cFileName);
|
|
|
|
|
|
|
|
|
|
_pMP3List = new tMP3Entry;
|
|
|
|
|
|
|
|
|
|
if ( _pMP3List == NULL )
|
|
|
|
|
{
|
|
|
|
|
FindClose(hFind);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bInitFirstEntry = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
strcat(filepath, " - NOT A VALID MP3");
|
|
|
|
|
|
|
|
|
|
OutputDebugString(filepath);
|
|
|
|
|
|
|
|
|
|
bInitFirstEntry = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while ( true )
|
|
|
|
|
{
|
|
|
|
|
if ( !FindNextFile(hFind, &fd) )
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if ( bInitFirstEntry )
|
|
|
|
|
{
|
|
|
|
|
strcpy(filepath, _mp3DirectoryPath);
|
|
|
|
|
strcat(filepath, fd.cFileName);
|
|
|
|
|
|
|
|
|
|
size_t filepathlen = strlen(filepath);
|
|
|
|
|
|
|
|
|
|
if ( filepathlen > 0 )
|
|
|
|
|
{
|
|
|
|
|
if ( _ResolveLink(filepath, filepath) )
|
|
|
|
|
{
|
|
|
|
|
OutputDebugString("Resolving Link");
|
|
|
|
|
OutputDebugString(filepath);
|
|
|
|
|
bShortcut = true;
|
|
|
|
|
} else {
|
|
|
|
|
bShortcut = false;
|
|
|
|
|
if (filepathlen > MAX_PATH) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]);
|
|
|
|
|
|
|
|
|
|
if (aStream[0] && aStream[0]->IsOpened())
|
|
|
|
|
{
|
|
|
|
|
total_ms = aStream[0]->GetLengthMS();
|
|
|
|
|
delete aStream[0];
|
|
|
|
|
aStream[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;
|
|
|
|
|
|
|
|
|
|
bInitFirstEntry = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
strcat(filepath, " - NOT A VALID MP3");
|
|
|
|
|
OutputDebugString(filepath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
strcpy(filepath, _mp3DirectoryPath);
|
|
|
|
|
strcat(filepath, fd.cFileName);
|
|
|
|
|
|
|
|
|
|
size_t filepathlen = strlen(filepath);
|
|
|
|
|
|
|
|
|
|
if ( filepathlen > 0 )
|
|
|
|
|
{
|
|
|
|
|
if ( _ResolveLink(filepath, filepath) )
|
|
|
|
|
{
|
|
|
|
|
OutputDebugString("Resolving Link");
|
|
|
|
|
OutputDebugString(filepath);
|
|
|
|
|
bShortcut = true;
|
|
|
|
|
} else
|
|
|
|
|
bShortcut = false;
|
|
|
|
|
|
|
|
|
|
aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]);
|
|
|
|
|
|
|
|
|
|
if (aStream[0] && aStream[0]->IsOpened())
|
|
|
|
|
{
|
|
|
|
|
total_ms = aStream[0]->GetLengthMS();
|
|
|
|
|
delete aStream[0];
|
|
|
|
|
aStream[0] = NULL;
|
|
|
|
|
|
|
|
|
|
OutputDebugString(fd.cFileName);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
strcat(filepath, " - NOT A VALID MP3");
|
|
|
|
|
OutputDebugString(filepath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
@ -566,56 +989,15 @@ 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();
|
|
|
|
|
|
|
|
|
|
if ( !InitialiseSampleBanks() )
|
|
|
|
|
{
|
|
|
|
|
Terminate();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nSampleBankMemoryStartAddress[SFX_BANK_0] = (uintptr)malloc(nSampleBankSize[SFX_BANK_0]);
|
|
|
|
|
ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_0] != 0);
|
|
|
|
|
|
|
|
|
|
if ( nSampleBankMemoryStartAddress[SFX_BANK_0] == 0 )
|
|
|
|
|
{
|
|
|
|
|
Terminate();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
|
|
|
|
|
ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
_bSampmanInitialised = true;
|
|
|
|
|
|
|
|
|
|
if ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders )
|
|
|
|
|
{
|
|
|
|
|
set_new_provider(defaultProvider);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Terminate();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef AUDIO_CACHE
|
|
|
|
|
FILE *cacheFile = fopen("audio\\sound.cache", "rb");
|
|
|
|
|
FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb");
|
|
|
|
|
if (cacheFile) {
|
|
|
|
|
fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
|
|
|
|
|
fclose(cacheFile);
|
|
|
|
@ -639,13 +1021,116 @@ cSampleManager::Initialise(void)
|
|
|
|
|
USERERROR("Can't open '%s'\n", StreamedNameTable[i]);
|
|
|
|
|
}
|
|
|
|
|
#ifdef AUDIO_CACHE
|
|
|
|
|
cacheFile = fopen("audio\\sound.cache", "wb");
|
|
|
|
|
cacheFile = fcaseopen("audio\\sound.cache", "wb");
|
|
|
|
|
fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
|
|
|
|
|
fclose(cacheFile);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
if ( !InitialiseSampleBanks() )
|
|
|
|
|
{
|
|
|
|
|
Terminate();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LoadSampleBank(SFX_BANK_0);
|
|
|
|
|
nSampleBankMemoryStartAddress[SFX_BANK_0] = (uintptr)malloc(nSampleBankSize[SFX_BANK_0]);
|
|
|
|
|
ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_0] != 0);
|
|
|
|
|
|
|
|
|
|
if ( nSampleBankMemoryStartAddress[SFX_BANK_0] == 0 )
|
|
|
|
|
{
|
|
|
|
|
Terminate();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] = (uintptr)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
|
|
|
|
|
ASSERT(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] != 0);
|
|
|
|
|
|
|
|
|
|
LoadSampleBank(SFX_BANK_0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
for ( int32 i = 0; i < MAX_STREAMS; i++ )
|
|
|
|
|
{
|
|
|
|
|
aStream[i] = NULL;
|
|
|
|
|
nStreamVolume[i] = 100;
|
|
|
|
|
nStreamPan[i] = 63;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
_bSampmanInitialised = true;
|
|
|
|
|
|
|
|
|
|
if ( defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders )
|
|
|
|
|
{
|
|
|
|
|
set_new_provider(defaultProvider);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Terminate();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -653,8 +1138,6 @@ cSampleManager::Initialise(void)
|
|
|
|
|
void
|
|
|
|
|
cSampleManager::Terminate(void)
|
|
|
|
|
{
|
|
|
|
|
release_existing();
|
|
|
|
|
|
|
|
|
|
for (int32 i = 0; i < MAX_STREAMS; i++)
|
|
|
|
|
{
|
|
|
|
|
CStream *stream = aStream[i];
|
|
|
|
@ -665,6 +1148,10 @@ cSampleManager::Terminate(void)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
release_existing();
|
|
|
|
|
|
|
|
|
|
_DeleteMP3Entries();
|
|
|
|
|
|
|
|
|
|
CStream::Terminate();
|
|
|
|
|
|
|
|
|
|
if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 )
|
|
|
|
@ -752,7 +1239,7 @@ cSampleManager::SetMonoMode(uint8 nMode)
|
|
|
|
|
bool
|
|
|
|
|
cSampleManager::LoadSampleBank(uint8 nBank)
|
|
|
|
|
{
|
|
|
|
|
ASSERT( nBank < MAX_SFX_BANKS );
|
|
|
|
|
ASSERT( nBank < MAX_SFX_BANKS);
|
|
|
|
|
|
|
|
|
|
if ( CTimer::GetIsCodePaused() )
|
|
|
|
|
return false;
|
|
|
|
@ -793,7 +1280,7 @@ cSampleManager::LoadSampleBank(uint8 nBank)
|
|
|
|
|
void
|
|
|
|
|
cSampleManager::UnloadSampleBank(uint8 nBank)
|
|
|
|
|
{
|
|
|
|
|
ASSERT( nBank < MAX_SFX_BANKS );
|
|
|
|
|
ASSERT( nBank < MAX_SFX_BANKS);
|
|
|
|
|
|
|
|
|
|
bSampleBankLoaded[nBank] = false;
|
|
|
|
|
}
|
|
|
|
@ -801,7 +1288,7 @@ cSampleManager::UnloadSampleBank(uint8 nBank)
|
|
|
|
|
bool
|
|
|
|
|
cSampleManager::IsSampleBankLoaded(uint8 nBank)
|
|
|
|
|
{
|
|
|
|
|
ASSERT( nBank < MAX_SFX_BANKS );
|
|
|
|
|
ASSERT( nBank < MAX_SFX_BANKS);
|
|
|
|
|
|
|
|
|
|
return bSampleBankLoaded[nBank];
|
|
|
|
|
}
|
|
|
|
@ -1225,7 +1712,7 @@ cSampleManager::StopChannel(uint32 nChannel)
|
|
|
|
|
void
|
|
|
|
|
cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
|
|
|
|
|
{
|
|
|
|
|
char filename[256];
|
|
|
|
|
char filename[MAX_PATH];
|
|
|
|
|
|
|
|
|
|
ASSERT( nStream < MAX_STREAMS );
|
|
|
|
|
|
|
|
|
@ -1283,6 +1770,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
|
|
|
|
|
bool
|
|
|
|
|
cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
|
|
|
|
|
{
|
|
|
|
|
uint32 position = nPos;
|
|
|
|
|
char filename[256];
|
|
|
|
|
|
|
|
|
|
ASSERT( nStream < MAX_STREAMS );
|
|
|
|
@ -1295,6 +1783,135 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
|
|
|
|
|
aStream[nStream] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
strcat(filename, StreamedNameTable[nFile]);
|
|
|
|
|
|
|
|
|
|
CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
|
|
|
|
ASSERT(stream != NULL);
|
|
|
|
|
|
|
|
|
|
aStream[nStream] = stream;
|
|
|
|
|
|
|
|
|
|
if (stream->IsOpened()) {
|
|
|
|
|
if (stream->Setup()) {
|
|
|
|
|
if (position != 0)
|
|
|
|
|
stream->SetPosMS(position);
|
|
|
|
|
|
|
|
|
|
stream->Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
delete stream;
|
|
|
|
|
aStream[nStream] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mp3->pLinkPath != NULL)
|
|
|
|
|
aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
|
|
|
|
else {
|
|
|
|
|
strcpy(filename, _mp3DirectoryPath);
|
|
|
|
|
strcat(filename, mp3->aFilename);
|
|
|
|
|
|
|
|
|
|
aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aStream[nStream]->IsOpened()) {
|
|
|
|
|
if (aStream[nStream]->Setup()) {
|
|
|
|
|
aStream[nStream]->Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
delete aStream[nStream];
|
|
|
|
|
aStream[nStream] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bIsMp3Active = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] )
|
|
|
|
|
position = 0;
|
|
|
|
|
|
|
|
|
|
tMP3Entry *e;
|
|
|
|
|
if ( !_GetMP3PosFromStreamPos(&position, &e) )
|
|
|
|
|
{
|
|
|
|
|
if ( e == NULL )
|
|
|
|
|
{
|
|
|
|
|
nFile = 0;
|
|
|
|
|
strcat(filename, StreamedNameTable[nFile]);
|
|
|
|
|
CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
|
|
|
|
ASSERT(stream != NULL);
|
|
|
|
|
|
|
|
|
|
aStream[nStream] = stream;
|
|
|
|
|
|
|
|
|
|
if (stream->IsOpened()) {
|
|
|
|
|
if (stream->Setup()) {
|
|
|
|
|
if (position != 0)
|
|
|
|
|
stream->SetPosMS(position);
|
|
|
|
|
|
|
|
|
|
stream->Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
delete stream;
|
|
|
|
|
aStream[nStream] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e->pLinkPath != NULL)
|
|
|
|
|
aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
|
|
|
|
else {
|
|
|
|
|
strcpy(filename, _mp3DirectoryPath);
|
|
|
|
|
strcat(filename, e->aFilename);
|
|
|
|
|
|
|
|
|
|
aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aStream[nStream]->IsOpened()) {
|
|
|
|
|
if (aStream[nStream]->Setup()) {
|
|
|
|
|
if (position != 0)
|
|
|
|
|
aStream[nStream]->SetPosMS(position);
|
|
|
|
|
|
|
|
|
|
aStream[nStream]->Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bIsMp3Active = true;
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
delete aStream[nStream];
|
|
|
|
|
aStream[nStream] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bIsMp3Active = false;
|
|
|
|
|
|
|
|
|
|
} while(++i < nNumMP3s);
|
|
|
|
|
|
|
|
|
|
position = 0;
|
|
|
|
|
nFile = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcpy(filename, StreamedNameTable[nFile]);
|
|
|
|
|
|
|
|
|
|
CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
|
|
|
@ -1302,21 +1919,16 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
|
|
|
|
|
|
|
|
|
|
aStream[nStream] = stream;
|
|
|
|
|
|
|
|
|
|
if ( stream->IsOpened() )
|
|
|
|
|
{
|
|
|
|
|
nStreamLength[nFile] = stream->GetLengthMS();
|
|
|
|
|
if ( stream->Setup() )
|
|
|
|
|
{
|
|
|
|
|
if ( nPos != 0 )
|
|
|
|
|
stream->SetPosMS(nPos);
|
|
|
|
|
|
|
|
|
|
if ( stream->IsOpened() ) {
|
|
|
|
|
if ( stream->Setup() ) {
|
|
|
|
|
if (position != 0)
|
|
|
|
|
stream->SetPosMS(position);
|
|
|
|
|
|
|
|
|
|
stream->Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
} else {
|
|
|
|
|
delete stream;
|
|
|
|
|
aStream[nStream] = NULL;
|
|
|
|
|
}
|
|
|
|
@ -1468,5 +2080,4 @@ cSampleManager::InitialiseSampleBanks(void)
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|