summaryrefslogtreecommitdiffstats
path: root/src/audio
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio')
-rw-r--r--src/audio/AudioLogic.cpp75
-rw-r--r--src/audio/AudioManager.cpp5
-rw-r--r--src/audio/AudioManager.h4
-rw-r--r--src/audio/DMAudio.cpp29
-rw-r--r--src/audio/DMAudio.h4
-rw-r--r--src/audio/MusicManager.cpp2
-rw-r--r--src/audio/PoliceRadio.cpp20
-rw-r--r--src/audio/oal/channel.cpp134
-rw-r--r--src/audio/oal/channel.h18
-rw-r--r--src/audio/oal/stream.cpp20
-rw-r--r--src/audio/sampman.h10
-rw-r--r--src/audio/sampman_miles.cpp2
-rw-r--r--src/audio/sampman_oal.cpp851
13 files changed, 834 insertions, 340 deletions
diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp
index 5d72f099..3fc9334f 100644
--- a/src/audio/AudioLogic.cpp
+++ b/src/audio/AudioLogic.cpp
@@ -1,4 +1,4 @@
-#include "common.h"
+#include "common.h"
#include "AudioManager.h"
#include "audio_enums.h"
@@ -4107,14 +4107,13 @@ cAudioManager::GetArmyTalkSfx(int16 sound)
PedState pedState;
static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
+ switch(sound) {
case SOUND_PED_PURSUIT_ARMY:
pedState = FindPlayerPed()->m_nPedState;
- if (pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE)
- return NO_SAMPLE;
+ if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) return NO_SAMPLE;
GetPhrase(&sfx, &lastSfx, SFX_ARMY_VOICE_1_CHASE_1, 15);
- default:
- return GetGenericMaleTalkSfx(sound);
+ break;
+ default: return GetGenericMaleTalkSfx(sound);
}
return (SFX_ARMY_VOICE_2_CHASE_1 - SFX_ARMY_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
@@ -4602,32 +4601,16 @@ cAudioManager::GetBlackProjectMaleTalkSfx(int16 sound, int32 model)
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_1, 6);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1, 7);
- break;
- case SOUND_PED_CHAT_SEXY:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_1, 3);
- break;
- case SOUND_PED_CHAT:
- GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_1, 6);
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_MUGGED_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_1, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1, 7); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_1, 3); break;
+ case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_1, 6); break;
+ default: return GetGenericMaleTalkSfx(sound);
}
if (model == MI_P_MAN2)
@@ -4641,26 +4624,14 @@ cAudioManager::GetWhiteFatMaleTalkSfx(int16 sound)
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_1, 3);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DODGE_1, 9);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 9);
- break;
- case SOUND_PED_WAIT_DOUBLEBACK:
- GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_LOST_1, 2);
- break;
- case SOUND_PED_CHAT:
- GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CHAT_1, 9);
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_1, 3); break;
+ case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_1, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DODGE_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_LOST_1, 2); break;
+ case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CHAT_1, 9); break;
+ default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
}
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index a42aa16f..d8054181 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -321,8 +321,13 @@ cAudioManager::Get3DProviderName(uint8 id) const
{
if (!m_bIsInitialised)
return nil;
+#ifdef AUDIO_OAL
+ id = clamp(id, 0, SampleManager.GetNum3DProvidersAvailable() - 1);
+#else
+ // We don't want that either since it will crash the game, but skipping for now
if (id >= SampleManager.GetNum3DProvidersAvailable())
return nil;
+#endif
return SampleManager.Get3DProviderName(id);
}
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index a1aa96f5..40a2d056 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -432,7 +432,7 @@ public:
void ReleaseDigitalHandle() const;
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2,
float collisionPower, float intensity2);
- void ReportCrime(int32 crime, const CVector *pos);
+ void ReportCrime(eCrimeType crime, const CVector &pos);
void ResetAudioLogicTimers(uint32 timer);
void ResetPoliceRadio();
void ResetTimers(uint32 time);
@@ -440,7 +440,7 @@ public:
void Service();
void ServiceCollisions();
void ServicePoliceRadio();
- void ServicePoliceRadioChannel(int32 wantedLevel);
+ void ServicePoliceRadioChannel(uint8 wantedLevel);
void ServiceSoundEffects();
int8 SetCurrent3DProvider(uint8 which);
void SetDynamicAcousticModelingStatus(uint8 status);
diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp
index 7174c23c..1027a084 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -5,9 +5,6 @@
#include "AudioManager.h"
#include "AudioScriptObject.h"
#include "sampman.h"
-#include "Font.h"
-#include "Text.h"
-#include "crossplatform.h"
cDMAudio DMAudio;
@@ -113,28 +110,6 @@ cDMAudio::Get3DProviderName(uint8 id)
return AudioManager.Get3DProviderName(id);
}
-int8 cDMAudio::AutoDetect3DProviders(void)
-{
- for ( int32 i = 0; i < GetNum3DProvidersAvailable(); i++ )
- {
- wchar buff[64];
-
- char *name = Get3DProviderName(i);
- AsciiToUnicode(name, buff);
- char *providername = UnicodeToAscii(buff);
- strupr(providername);
-#if defined(AUDIO_MSS)
- if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") )
- return i;
-#elif defined(AUDIO_OAL)
- if ( !strcmp(providername, "OPENAL SOFT") )
- return i;
-#endif
- }
-
- return -1;
-}
-
int8
cDMAudio::GetCurrent3DProviderIndex(void)
{
@@ -198,7 +173,7 @@ cDMAudio::IsAudioInitialised(void)
void
cDMAudio::ReportCrime(eCrimeType crime, const CVector &pos)
{
- AudioManager.ReportCrime(crime, &pos);
+ AudioManager.ReportCrime(crime, pos);
}
int32
@@ -345,7 +320,7 @@ cDMAudio::SetRadioInCar(uint32 radio)
}
void
-cDMAudio::SetRadioChannel(int8 radio, int32 pos)
+cDMAudio::SetRadioChannel(uint8 radio, int32 pos)
{
MusicManager.SetRadioChannelByScript(radio, pos);
}
diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h
index bb95f303..3e6d5603 100644
--- a/src/audio/DMAudio.h
+++ b/src/audio/DMAudio.h
@@ -35,8 +35,6 @@ public:
uint8 GetNum3DProvidersAvailable(void);
char *Get3DProviderName(uint8 id);
- int8 AutoDetect3DProviders(void);
-
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
@@ -86,6 +84,6 @@ public:
uint8 GetRadioInCar(void);
void SetRadioInCar(uint32 radio);
- void SetRadioChannel(int8 radio, int32 pos);
+ void SetRadioChannel(uint8 radio, int32 pos);
};
extern cDMAudio DMAudio;
diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index 5519d899..10862cdc 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -161,7 +161,7 @@ cMusicManager::DisplayRadioStationName()
CFont::SetPropOn();
CFont::SetFontStyle(FONT_HEADING);
CFont::SetCentreOn();
- CFont::SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
+ CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH));
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation);
diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp
index 4d0f8909..665494a3 100644
--- a/src/audio/PoliceRadio.cpp
+++ b/src/audio/PoliceRadio.cpp
@@ -91,7 +91,7 @@ cAudioManager::InitialisePoliceRadio()
m_sPoliceRadioQueue.policeChannelTimerSeconds = 0;
m_sPoliceRadioQueue.policeChannelCounterSeconds = 0;
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++)
- m_sPoliceRadioQueue.crimes[i].type = 0;
+ m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
SampleManager.SetChannelReverbFlag(policeChannel, 0);
gSpecialSuspectLastSeenReport = false;
@@ -154,7 +154,7 @@ cAudioManager::ServicePoliceRadio()
if(!m_bIsInitialised) return;
- if(!m_nUserPause) {
+ if(m_nUserPause == 0) {
bool crimeReport = SetupCrimeReport();
#ifdef FIX_BUGS // Crash at 0x5fe6ef
if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
@@ -162,8 +162,8 @@ cAudioManager::ServicePoliceRadio()
#endif
wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel;
if(!crimeReport) {
- if(wantedLevel) {
- if(nLastSeen) {
+ if(wantedLevel != 0) {
+ if(nLastSeen != 0) {
--nLastSeen;
} else {
nLastSeen = m_anRandomTable[1] % 1000 + 2000;
@@ -176,7 +176,7 @@ cAudioManager::ServicePoliceRadio()
}
void
-cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel)
+cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
{
bool processed = false;
uint32 sample;
@@ -189,7 +189,7 @@ cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel)
if (!m_bIsInitialised) return;
- if (m_nUserPause) {
+ if (m_nUserPause != 0) {
if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == 1 &&
SampleManager.IsStreamPlaying(1)) {
@@ -241,7 +241,7 @@ cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel)
} else {
sample = TOTAL_AUDIO_SAMPLES;
}
- if (!wantedLevel) {
+ if (wantedLevel == 0) {
if (gSpecialSuspectLastSeenReport) {
gSpecialSuspectLastSeenReport = 0;
} else if (((sample >= SFX_POLICE_RADIO_MESSAGE_NOISE_1) && (sample <= SFX_POLICE_RADIO_MESSAGE_NOISE_3)) || sample == TOTAL_AUDIO_SAMPLES) {
@@ -675,7 +675,7 @@ cAudioManager::SetupSuspectLastSeenReport()
void
-cAudioManager::ReportCrime(int32 type, const CVector *pos)
+cAudioManager::ReportCrime(eCrimeType type, const CVector &pos)
{
int32 lastCrime = ARRAY_SIZE(m_sPoliceRadioQueue.crimes);
if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 &&
@@ -683,7 +683,7 @@ cAudioManager::ReportCrime(int32 type, const CVector *pos)
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
if (m_sPoliceRadioQueue.crimes[i].type) {
if (m_sPoliceRadioQueue.crimes[i].type == type) {
- m_sPoliceRadioQueue.crimes[i].position = *pos;
+ m_sPoliceRadioQueue.crimes[i].position = pos;
m_sPoliceRadioQueue.crimes[i].timer = 0;
return;
}
@@ -694,7 +694,7 @@ cAudioManager::ReportCrime(int32 type, const CVector *pos)
if (lastCrime < ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) {
m_sPoliceRadioQueue.crimes[lastCrime].type = type;
- m_sPoliceRadioQueue.crimes[lastCrime].position = *pos;
+ m_sPoliceRadioQueue.crimes[lastCrime].position = pos;
m_sPoliceRadioQueue.crimes[lastCrime].timer = 0;
gMinTimeToNextReport[type] = m_FrameCounter + 500;
}
diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp
index 731e3581..673a4aed 100644
--- a/src/audio/oal/channel.cpp
+++ b/src/audio/oal/channel.cpp
@@ -10,17 +10,49 @@
extern bool IsFXSupported();
+ALuint alSources[MAXCHANNELS+MAX2DCHANNELS];
+ALuint alFilters[MAXCHANNELS+MAX2DCHANNELS];
+ALuint alBuffers[MAXCHANNELS+MAX2DCHANNELS];
+bool bChannelsCreated = false;
+
+void
+CChannel::InitChannels()
+{
+ alGenSources(MAXCHANNELS+MAX2DCHANNELS, alSources);
+ alGenBuffers(MAXCHANNELS+MAX2DCHANNELS, alBuffers);
+ if (IsFXSupported())
+ alGenFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters);
+ bChannelsCreated = true;
+}
+
+void
+CChannel::DestroyChannels()
+{
+ if (bChannelsCreated)
+ {
+ alDeleteSources(MAXCHANNELS + MAX2DCHANNELS, alSources);
+ memset(alSources, 0, sizeof(alSources));
+ alDeleteBuffers(MAXCHANNELS + MAX2DCHANNELS, alBuffers);
+ memset(alBuffers, 0, sizeof(alBuffers));
+ if (IsFXSupported())
+ {
+ alDeleteFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters);
+ memset(alFilters, 0, sizeof(alFilters));
+ }
+ bChannelsCreated = false;
+ }
+}
+
+
CChannel::CChannel()
{
- alSource = AL_NONE;
- alFilter = AL_FILTER_NULL;
+ Data = nil;
+ DataSize = 0;
SetDefault();
}
void CChannel::SetDefault()
{
- alBuffer = AL_NONE;
-
Pitch = 1.0f;
Gain = 1.0f;
Mix = 0.0f;
@@ -39,25 +71,19 @@ void CChannel::Reset()
SetDefault();
}
-void CChannel::Init(bool Is2D)
+void CChannel::Init(uint32 _id, bool Is2D)
{
- ASSERT(!HasSource());
- alGenSources(1, &alSource);
+ id = _id;
if ( HasSource() )
{
- alSourcei(alSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ alSourcei(alSources[id], AL_SOURCE_RELATIVE, AL_TRUE);
if ( IsFXSupported() )
- alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
+ alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
if ( Is2D )
{
- alSource3f(alSource, AL_POSITION, 0.0f, 0.0f, 0.0f);
- alSourcef (alSource, AL_GAIN, 1.0f);
- }
- else
- {
- if ( IsFXSupported() )
- alGenFilters(1,&alFilter);
+ alSource3f(alSources[id], AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alSourcef(alSources[id], AL_GAIN, 1.0f);
}
}
}
@@ -69,39 +95,34 @@ void CChannel::Term()
{
if ( IsFXSupported() )
{
- alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
-
- if(alFilter != AL_FILTER_NULL)
- alDeleteFilters(1,&alFilter);
+ alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
}
-
- alDeleteSources(1, &alSource);
}
- alSource = AL_NONE;
- alFilter = AL_FILTER_NULL;
}
void CChannel::Start()
{
if ( !HasSource() ) return;
-
+ if ( !Data ) return;
+
+ alBufferData(alBuffers[id], AL_FORMAT_MONO16, Data, DataSize, Frequency);
if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 )
- alBufferiv(alBuffer, AL_LOOP_POINTS_SOFT, LoopPoints);
- alSourcei (alSource, AL_BUFFER, alBuffer);
- alSourcePlay(alSource);
+ alBufferiv(alBuffers[id], AL_LOOP_POINTS_SOFT, LoopPoints);
+ alSourcei(alSources[id], AL_BUFFER, alBuffers[id]);
+ alSourcePlay(alSources[id]);
}
void CChannel::Stop()
{
if ( HasSource() )
- alSourceStop(alSource);
+ alSourceStop(alSources[id]);
Reset();
}
bool CChannel::HasSource()
{
- return alSource != AL_NONE;
+ return alSources[id] != AL_NONE;
}
bool CChannel::IsUsed()
@@ -109,7 +130,7 @@ bool CChannel::IsUsed()
if ( HasSource() )
{
ALint sourceState;
- alGetSourcei(alSource, AL_SOURCE_STATE, &sourceState);
+ alGetSourcei(alSources[id], AL_SOURCE_STATE, &sourceState);
return sourceState == AL_PLAYING;
}
return false;
@@ -118,27 +139,24 @@ bool CChannel::IsUsed()
void CChannel::SetPitch(float pitch)
{
if ( !HasSource() ) return;
- alSourcef(alSource, AL_PITCH, pitch);
+ alSourcef(alSources[id], AL_PITCH, pitch);
}
void CChannel::SetGain(float gain)
{
if ( !HasSource() ) return;
- alSourcef(alSource, AL_GAIN, gain);
+ alSourcef(alSources[id], 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)
+
+void CChannel::SetSampleData(void *_data, size_t _DataSize, int32 freq)
{
+ Data = _data;
+ DataSize = _DataSize;
Frequency = freq;
}
@@ -150,7 +168,7 @@ void CChannel::SetCurrentFreq(uint32 freq)
void CChannel::SetLoopCount(int32 loopCount) // fake. TODO:
{
if ( !HasSource() ) return;
- alSourcei(alSource, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
+ alSourcei(alSources[id], AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
}
void CChannel::SetLoopPoints(ALint start, ALint end)
@@ -162,53 +180,49 @@ void CChannel::SetLoopPoints(ALint start, ALint end)
void CChannel::SetPosition(float x, float y, float z)
{
if ( !HasSource() ) return;
- alSource3f(alSource, AL_POSITION, x, y, z);
+ alSource3f(alSources[id], AL_POSITION, x, y, z);
}
void CChannel::SetDistances(float max, float min)
{
if ( !HasSource() ) return;
- alSourcef (alSource, AL_MAX_DISTANCE, max);
- alSourcef (alSource, AL_REFERENCE_DISTANCE, min);
- alSourcef (alSource, AL_MAX_GAIN, 1.0f);
- alSourcef (alSource, AL_ROLLOFF_FACTOR, 1.0f);
+ alSourcef (alSources[id], AL_MAX_DISTANCE, max);
+ alSourcef (alSources[id], AL_REFERENCE_DISTANCE, min);
+ alSourcef (alSources[id], AL_MAX_GAIN, 1.0f);
+ alSourcef (alSources[id], AL_ROLLOFF_FACTOR, 1.0f);
}
-void CChannel::SetPan(uint32 pan)
+void CChannel::SetPan(int32 pan)
{
SetPosition((pan-63)/64.0f, 0.0f, Sqrt(1.0f-SQR((pan-63)/64.0f)));
}
-void CChannel::SetBuffer(ALuint buffer)
-{
- alBuffer = buffer;
-}
-
void CChannel::ClearBuffer()
{
if ( !HasSource() ) return;
- SetBuffer(AL_NONE);
- alSourcei(alSource, AL_BUFFER, AL_NONE);
+ alSourcei(alSources[id], AL_BUFFER, AL_NONE);
+ Data = nil;
+ DataSize = 0;
}
void CChannel::SetReverbMix(ALuint slot, float mix)
{
if ( !IsFXSupported() ) return;
if ( !HasSource() ) return;
- if ( alFilter == AL_FILTER_NULL ) return;
+ if ( alFilters[id] == AL_FILTER_NULL ) return;
Mix = mix;
- EAX3_SetReverbMix(alFilter, mix);
- alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+ EAX3_SetReverbMix(alFilters[id], mix);
+ alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, slot, 0, alFilters[id]);
}
void CChannel::UpdateReverb(ALuint slot)
{
if ( !IsFXSupported() ) return;
if ( !HasSource() ) return;
- if ( alFilter == AL_FILTER_NULL ) return;
- EAX3_SetReverbMix(alFilter, Mix);
- alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+ if ( alFilters[id] == AL_FILTER_NULL ) return;
+ EAX3_SetReverbMix(alFilters[id], Mix);
+ alSource3i(alSources[id], AL_AUXILIARY_SEND_FILTER, slot, 0, alFilters[id]);
}
#endif
diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h
index 0c86bdc6..81817a32 100644
--- a/src/audio/oal/channel.h
+++ b/src/audio/oal/channel.h
@@ -9,22 +9,24 @@
class CChannel
{
- ALuint alSource;
- ALuint alFilter;
- ALuint alBuffer;
+ uint32 id;
float Pitch, Gain;
float Mix;
+ void *Data;
+ size_t DataSize;
int32 Frequency;
float Position[3];
float Distances[2];
int32 LoopCount;
ALint LoopPoints[2];
- uint32 Sample;
public:
+ static void InitChannels();
+ static void DestroyChannels();
+
CChannel();
void SetDefault();
void Reset();
- void Init(bool Is2D = false);
+ void Init(uint32 _id, bool Is2D = false);
void Term();
void Start();
void Stop();
@@ -33,15 +35,13 @@ public:
void SetPitch(float pitch);
void SetGain(float gain);
void SetVolume(int32 vol);
- void SetSampleID(uint32 nSfx);
- void SetFreq(int32 freq);
+ void SetSampleData(void *_data, size_t _DataSize, 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 SetPan(int32 pan);
void ClearBuffer();
void SetReverbMix(ALuint slot, float mix);
void UpdateReverb(ALuint slot);
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index c4f1b67c..3adb702a 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -195,7 +195,7 @@ public:
if (m_FileH) {
m_nChannels = op_head(m_FileH, 0)->channel_count;
- m_nRate = op_head(m_FileH, 0)->input_sample_rate;
+ m_nRate = 48000;
const OpusTags *tags = op_tags(m_FileH, 0);
for (int i = 0; i < tags->comments; i++) {
if (strncmp(tags->user_comments[i], "SAMPLERATE", sizeof("SAMPLERATE")-1) == 0)
@@ -323,8 +323,8 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF
#endif
else
m_pSoundFile = nil;
- ASSERT(m_pSoundFile != nil);
- if (m_pSoundFile && m_pSoundFile->IsOpened() )
+
+ if ( IsOpened() )
{
m_pBuffer = malloc(m_pSoundFile->GetBufferSize());
ASSERT(m_pBuffer!=nil);
@@ -371,14 +371,14 @@ bool CStream::HasSource()
bool CStream::IsOpened()
{
- return m_pSoundFile->IsOpened();
+ return m_pSoundFile && m_pSoundFile->IsOpened();
}
bool CStream::IsPlaying()
{
if ( !HasSource() || !IsOpened() ) return false;
- if ( m_pSoundFile->IsOpened() && !m_bPaused )
+ if ( !m_bPaused )
{
ALint sourceState;
alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
@@ -446,7 +446,7 @@ void CStream::SetPan(uint8 nPan)
void CStream::SetPosMS(uint32 nPos)
{
- if ( !m_pSoundFile->IsOpened() ) return;
+ if ( !IsOpened() ) return;
m_pSoundFile->Seek(nPos);
ClearBuffers();
}
@@ -454,7 +454,7 @@ void CStream::SetPosMS(uint32 nPos)
uint32 CStream::GetPosMS()
{
if ( !HasSource() ) return 0;
- if ( !m_pSoundFile->IsOpened() ) return 0;
+ if ( !IsOpened() ) return 0;
ALint offset;
//alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
@@ -467,7 +467,7 @@ uint32 CStream::GetPosMS()
uint32 CStream::GetLengthMS()
{
- if ( !m_pSoundFile->IsOpened() ) return 0;
+ if ( !IsOpened() ) return 0;
return m_pSoundFile->GetLength();
}
@@ -475,7 +475,7 @@ bool CStream::FillBuffer(ALuint alBuffer)
{
if ( !HasSource() )
return false;
- if ( !m_pSoundFile->IsOpened() )
+ if ( !IsOpened() )
return false;
if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) )
return false;
@@ -517,7 +517,7 @@ void CStream::ClearBuffers()
bool CStream::Setup()
{
- if ( m_pSoundFile->IsOpened() )
+ if ( IsOpened() )
{
m_pSoundFile->Seek(0);
alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE);
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index d4b2621a..2284d385 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -153,11 +153,7 @@ public:
bool Initialise(void);
void Terminate (void);
-
-#ifdef AUDIO_OAL
- void UpdateSoundBuffers(void);
-#endif
-
+
bool CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter (void);
@@ -218,6 +214,10 @@ public:
extern cSampleManager SampleManager;
extern uint32 BankStartOffset[MAX_SFX_BANKS];
+#ifdef AUDIO_OAL
+extern int defaultProvider;
+#endif
+
#ifdef AUDIO_OPUS
static char StreamedNameTable[][25] = {
"AUDIO\\HEAD.OPUS", "AUDIO\\CLASS.OPUS", "AUDIO\\KJAH.OPUS", "AUDIO\\RISE.OPUS", "AUDIO\\LIPS.OPUS", "AUDIO\\GAME.OPUS",
diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp
index 70ea942e..185e08d6 100644
--- a/src/audio/sampman_miles.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -2331,4 +2331,4 @@ cSampleManager::InitialiseSampleBanks(void)
return true;
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
index 9f3156cb..eec5ca5f 100644
--- a/src/audio/sampman_oal.cpp
+++ b/src/audio/sampman_oal.cpp
@@ -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;
@@ -88,51 +98,34 @@ 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
+
+struct tMP3Entry
{
- ALuint buffer;
- ALuint timer;
+ char aFilename[MAX_PATH];
- 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 nTrackLength;
+ uint32 nTrackStreamPos;
-uint32 nNumMP3s;
+ 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 =
@@ -256,12 +249,7 @@ release_existing()
alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
}
- alDeleteBuffers(MAX_PEDSFX, pedBuffers);
-
- for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
- {
- ALBuffers[i].Term();
- }
+ CChannel::DestroyChannels();
if ( ALContext )
{
@@ -342,13 +330,6 @@ set_new_provider(int index)
stream->ProviderInit();
}
- for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
- {
- ALBuffers[i].Init();
- }
-
- alGenBuffers(MAX_PEDSFX, pedBuffers);
-
usingEAX = 0;
usingEAX3 = 0;
_usingEFX = false;
@@ -380,10 +361,12 @@ set_new_provider(int index)
}
//SampleManager.SetSpeakerConfig(speaker_type);
-
+
+ CChannel::InitChannels();
+
for ( int32 i = 0; i < MAXCHANNELS; i++ )
- aChannel[i].Init();
- aChannel[CHANNEL2D].Init(true);
+ aChannel[i].Init(i);
+ aChannel[CHANNEL2D].Init(CHANNEL2D, true);
if ( IsFXSupported() )
{
@@ -451,22 +434,419 @@ int8 cSampleManager::GetCurrent3DProviderIndex(void)
int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
{
- if (nProvider >= m_nNumberOfProviders)
- nProvider = 0;
- ASSERT( nProvider < m_nNumberOfProviders );
int savedprovider = curprovider;
+
+ 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];
- if ( nProvider < m_nNumberOfProviders )
+ CoInitialize(NULL);
+
+ if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) ))
{
- if ( set_new_provider(nProvider) )
- return curprovider;
- else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
- return curprovider;
+ 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
- return -1;
+ {
+ _pMP3List->pLinkPath = NULL;
+ }
+
+ bInitFirstEntry = false;
}
else
- return curprovider;
+ {
+ 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
@@ -566,21 +946,45 @@ 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();
-
+
+#ifdef AUDIO_CACHE
+ FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb");
+ if (cacheFile) {
+ fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
+ fclose(cacheFile);
+ } else
+#endif
+ {
+
+ 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]);
+ }
+#ifdef AUDIO_CACHE
+ cacheFile = fcaseopen("audio\\sound.cache", "wb");
+ fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
+ fclose(cacheFile);
+#endif
+ }
+
+ {
if ( !InitialiseSampleBanks() )
{
Terminate();
@@ -598,13 +1002,23 @@ cSampleManager::Initialise(void)
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 ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders )
+ if ( defaultProvider >= 0 && defaultProvider < m_nNumberOfProviders )
{
set_new_provider(defaultProvider);
}
@@ -614,38 +1028,66 @@ cSampleManager::Initialise(void)
return false;
}
}
-#ifdef AUDIO_CACHE
- FILE *cacheFile = fopen("audio\\sound.cache", "rb");
- if (cacheFile) {
- fread(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
- fclose(cacheFile);
- } else
-#endif
+
{
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- {
- aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]);
+ nNumMP3s = 0;
+
+ _pMP3List = NULL;
+
+ _FindMP3s();
+
+ if ( nNumMP3s != 0 )
+ {
+ nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0;
- if ( aStream[0] && aStream[0]->IsOpened() )
+ for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext )
{
- uint32 tatalms = aStream[0]->GetLengthMS();
- delete aStream[0];
- aStream[0] = NULL;
-
- nStreamLength[i] = tatalms;
+ 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
- USERERROR("Can't open '%s'\n", StreamedNameTable[i]);
+ {
+ 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;
+ }
}
-#ifdef AUDIO_CACHE
- cacheFile = fopen("audio\\sound.cache", "wb");
- fwrite(nStreamLength, sizeof(uint32), TOTAL_STREAMED_SOUNDS, cacheFile);
- fclose(cacheFile);
-#endif
- }
+ else
+ _CurMP3Pos = 0;
- LoadSampleBank(SFX_BANK_0);
+ _bIsMp3Active = false;
+ }
return true;
}
@@ -653,8 +1095,6 @@ cSampleManager::Initialise(void)
void
cSampleManager::Terminate(void)
{
- release_existing();
-
for (int32 i = 0; i < MAX_STREAMS; i++)
{
CStream *stream = aStream[i];
@@ -665,8 +1105,12 @@ cSampleManager::Terminate(void)
}
}
+ release_existing();
+
+ _DeleteMP3Entries();
+
CStream::Terminate();
-
+
if ( nSampleBankMemoryStartAddress[SFX_BANK_0] != 0 )
{
free((void *)nSampleBankMemoryStartAddress[SFX_BANK_0]);
@@ -682,15 +1126,6 @@ cSampleManager::Terminate(void)
_bSampmanInitialised = false;
}
-void
-cSampleManager::UpdateSoundBuffers(void)
-{
- for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
- {
- ALBuffers[i].Update();
- }
-}
-
bool cSampleManager::CheckForAnAudioFileOnCD(void)
{
return true;
@@ -752,7 +1187,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 +1228,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 +1236,7 @@ cSampleManager::UnloadSampleBank(uint8 nBank)
bool
cSampleManager::IsSampleBankLoaded(uint8 nBank)
{
- ASSERT( nBank < MAX_SFX_BANKS );
+ ASSERT( nBank < MAX_SFX_BANKS);
return bSampleBankLoaded[nBank];
}
@@ -899,13 +1334,7 @@ cSampleManager::LoadPedComment(uint32 nComment)
#endif
nPedSlotSfx[nCurrentPedSlot] = nComment;
-
- alBufferData(pedBuffers[nCurrentPedSlot],
- AL_FORMAT_MONO16,
- (void *)(nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE*nCurrentPedSlot),
- m_aSamples[nComment].nSize,
- m_aSamples[nComment].nFrequency);
-
+
if ( ++nCurrentPedSlot >= MAX_PEDSFX )
nCurrentPedSlot = 0;
@@ -1041,25 +1470,14 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
{
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
- ALuint buffer;
+ uintptr addr;
if ( nSfx < SAMPLEBANK_MAX )
{
if ( !IsSampleBankLoaded(nBank) )
return false;
- uintptr addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
-
- if ( ALBuffers[nSfx].IsEmpty() )
- {
- ALuint buf;
- alGenBuffers(1, &buf);
- alBufferData(buf, AL_FORMAT_MONO16, (void *)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency);
- ALBuffers[nSfx].Set(buf);
- }
- ALBuffers[nSfx].Wait();
-
- buffer = ALBuffers[nSfx].buffer;
+ addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
}
else
{
@@ -1067,14 +1485,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
return false;
int32 slot = _GetPedCommentSlot(nSfx);
-
- buffer = pedBuffers[slot];
- }
-
- if ( buffer == 0 )
- {
- TRACE("No buffer to play id %d", nSfx);
- return false;
+ addr = (nSampleBankMemoryStartAddress[SFX_BANK_PED_COMMENTS] + PED_BLOCKSIZE * slot);
}
if ( GetChannelUsedFlag(nChannel) )
@@ -1086,10 +1497,8 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
aChannel[nChannel].Reset();
if ( aChannel[nChannel].HasSource() )
{
- aChannel[nChannel].SetSampleID (nSfx);
- aChannel[nChannel].SetFreq (m_aSamples[nSfx].nFrequency);
+ aChannel[nChannel].SetSampleData ((void*)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency);
aChannel[nChannel].SetLoopPoints (0, -1);
- aChannel[nChannel].SetBuffer (buffer);
aChannel[nChannel].SetPitch (1.0f);
return true;
}
@@ -1225,7 +1634,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 +1692,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 +1705,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 +1841,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;
}
@@ -1415,8 +1949,6 @@ cSampleManager::Service(void)
if ( stream )
stream->Update();
}
-
- UpdateSoundBuffers();
}
bool
@@ -1468,5 +2000,4 @@ cSampleManager::InitialiseSampleBanks(void)
return true;
}
-
#endif