1
0
forked from 0ad/0ad

Sound system patch by stwf:

Fixes sound system to work with archives (use VFS files instead of
POSIX), fixes #1604.
Improves error handling and logging, refs #1594.
Allows sound to be disabled with -nosound/-quickstart runtime options or
--without-audio build option, fixes #1609, #1614.
Experimentally increases default buffer size to help prevent sound
stoppages.

This was SVN commit r12566.
This commit is contained in:
historic_bruno 2012-08-31 19:08:41 +00:00
parent e8758b8bf1
commit 89c8bccbde
29 changed files with 440 additions and 180 deletions

View File

@ -102,7 +102,7 @@ sound.musicgain = 0.2
sound.ambientgain = 0.6
sound.actiongain = 0.7
sound.bufferCount = 50
sound.bufferSize = 65536
sound.bufferSize = 98304
; Camera control settings
view.scroll.speed = 120.0

View File

@ -24,6 +24,7 @@
#include "graphics/ParticleManager.h"
#include "graphics/UnitManager.h"
#include "gui/GUIManager.h"
#include "lib/config2.h"
#include "lib/timer.h"
#include "network/NetClient.h"
#include "network/NetServer.h"
@ -294,7 +295,10 @@ bool CGame::Update(const double deltaRealTime, bool doInterpolate)
if (doInterpolate)
{
m_TurnManager->Interpolate(deltaSimTime, deltaRealTime);
g_SoundManager->IdleTask();
#if CONFIG2_AUDIO
if ( g_SoundManager )
g_SoundManager->IdleTask();
#endif
}
// TODO: maybe we should add a CCmpParticleInterface that passes the interpolation commands

View File

@ -84,6 +84,7 @@ static void LoadGlobals()
CFG_GET_USER_VAL("silhouettes", Bool, g_Silhouettes);
CFG_GET_USER_VAL("showsky", Bool, g_ShowSky);
#if CONFIG2_AUDIO
float gain = 0.5f;
float musicGain = 0.5f;
float ambientGain = 0.5f;
@ -99,12 +100,15 @@ static void LoadGlobals()
CFG_GET_USER_VAL("sound.bufferCount", Int, bufferCount);
CFG_GET_USER_VAL("sound.bufferSize", UnsignedLong, bufferSize);
g_SoundManager->SetMasterGain(gain);
g_SoundManager->SetMusicGain(musicGain);
g_SoundManager->SetAmbientGain(ambientGain);
g_SoundManager->SetActionGain(actionGain);
if ( g_SoundManager ) {
g_SoundManager->SetMasterGain(gain);
g_SoundManager->SetMusicGain(musicGain);
g_SoundManager->SetAmbientGain(ambientGain);
g_SoundManager->SetActionGain(actionGain);
g_SoundManager->SetMemoryUsage(bufferSize, bufferCount);
g_SoundManager->SetMemoryUsage(bufferSize, bufferCount);
}
#endif // CONFIG2_AUDIO
}

View File

@ -18,6 +18,7 @@
#include "precompiled.h"
#include "lib/app_hooks.h"
#include "lib/config2.h"
#include "lib/input.h"
#include "lib/ogl.h"
#include "lib/timer.h"
@ -190,8 +191,10 @@ void Render()
{
PROFILE3("render");
g_SoundManager->IdleTask();
#if CONFIG2_AUDIO
if (g_SoundManager)
g_SoundManager->IdleTask();
#endif
ogl_WarnIfError();
g_Profiler2.RecordGPUFrameStart();
@ -685,7 +688,10 @@ void Shutdown(int UNUSED(flags))
// resource
// first shut down all resource owners, and then the handle manager.
TIMER_BEGIN(L"resource modules");
delete g_SoundManager;
#if CONFIG2_AUDIO
if (g_SoundManager)
delete g_SoundManager;
#endif
g_VFS.reset();
@ -862,7 +868,10 @@ void Init(const CmdLineArgs& args, int UNUSED(flags))
g_ScriptStatsTable = new CScriptStatsTable;
g_ProfileViewer.AddRootTable(g_ScriptStatsTable);
g_SoundManager = new CSoundManager();
#if CONFIG2_AUDIO
CSoundManager::CreateSoundManager();
#endif
InitScripting(); // before GUI
@ -926,7 +935,9 @@ void InitGraphics(const CmdLineArgs& args, int flags)
// speed up startup by disabling all sound
// (OpenAL init will be skipped).
// must be called before first snd_open.
g_SoundManager->SetEnabled(false);
#if CONFIG2_AUDIO
CSoundManager::SetEnabled(false);
#endif
}
g_GUI = new CGUIManager(g_ScriptingHost.GetScriptInterface());

View File

@ -20,6 +20,7 @@
#include "simulation2/system/Component.h"
#include "ICmpSoundManager.h"
#include "lib/config2.h"
#include "ps/CLogger.h"
#include "simulation2/MessageTypes.h"
#include "simulation2/components/ICmpPosition.h"
@ -36,7 +37,9 @@ public:
DEFAULT_COMPONENT_ALLOCATOR(SoundManager)
#if CONFIG2_AUDIO
std::map<std::wstring, CSoundGroup*> m_SoundGroups;
#endif
static std::string GetSchema()
{
@ -49,9 +52,11 @@ public:
virtual void Deinit()
{
#if CONFIG2_AUDIO
for (std::map<std::wstring, CSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
delete it->second;
m_SoundGroups.clear();
#endif // CONFIG2_AUDIO
}
virtual void Serialize(ISerializer& UNUSED(serialize))
@ -71,6 +76,7 @@ public:
{
case MT_Update:
{
#if CONFIG2_AUDIO
// Update all the sound groups
// TODO: is it sensible to do this once per simulation turn, not once per renderer frame
// or on some other timer?
@ -79,6 +85,9 @@ public:
for (std::map<std::wstring, CSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
if (it->second)
it->second->Update(t);
#else // !CONFIG2_AUDIO
UNUSED2(msg);
#endif // !CONFIG2_AUDIO
break;
}
}
@ -86,6 +95,7 @@ public:
virtual void PlaySoundGroup(std::wstring name, entity_id_t source)
{
#if CONFIG2_AUDIO
// Make sure the sound group is loaded
CSoundGroup* group;
if (m_SoundGroups.find(name) == m_SoundGroups.end())
@ -127,7 +137,13 @@ public:
group->PlayNext(sourcePos);
}
#else // !CONFIG2_AUDIO
UNUSED2(name);
UNUSED2(source);
#endif // !CONFIG2_AUDIO
}
};
REGISTER_COMPONENT_TYPE(SoundManager)

View File

@ -27,8 +27,10 @@
#include "soundmanager/js/AmbientSound.h"
#include "soundmanager/js/MusicSound.h"
#include "soundmanager/js/Sound.h"
#include "ps/CLogger.h"
CSoundManager* g_SoundManager = NULL;
CSoundManager* g_SoundManager;
void CSoundManager::ScriptingInit()
{
@ -38,6 +40,40 @@ void CSoundManager::ScriptingInit()
JSoundPlayer::ScriptingInit();
}
#if CONFIG2_AUDIO
void CSoundManager::CreateSoundManager()
{
g_SoundManager = new CSoundManager();
}
void CSoundManager::SetEnabled(bool doEnable)
{
if ( g_SoundManager && !doEnable )
{
delete g_SoundManager;
g_SoundManager = NULL;
}
else if ( ! g_SoundManager && doEnable )
{
CSoundManager::CreateSoundManager();
}
}
void CSoundManager::al_ReportError(ALenum err, const char* caller, int line)
{
LOGERROR(L"OpenAL error: %hs; called from %hs (line %d)\n", alGetString(err), caller, line);
}
void CSoundManager::al_check(const char* caller, int line)
{
ALenum err = alGetError();
if (err != AL_NO_ERROR)
al_ReportError(err, caller, line);
}
CSoundManager::CSoundManager()
{
m_Items = new ItemsList;
@ -47,11 +83,10 @@ CSoundManager::CSoundManager()
m_MusicGain = 1;
m_AmbientGain = 1;
m_ActionGain = 1;
m_Enabled = true;
m_BufferCount = 50;
m_BufferSize = 65536;
m_MusicEnabled = true;
AlcInit();
m_Enabled = AlcInit() == INFO::OK;
}
CSoundManager::~CSoundManager()
@ -96,13 +131,13 @@ Status CSoundManager::AlcInit()
debug_printf(L"Sound: AlcInit success, using %hs\n", dev_name);
else
{
debug_printf(L"Sound: AlcInit failed, m_Device=%p m_Context=%p dev_name=%hs err=%d\n", m_Device, m_Context, dev_name, err);
LOGERROR(L"Sound: AlcInit failed, m_Device=%p m_Context=%p dev_name=%hs err=%d\n", m_Device, m_Context, dev_name, err);
// FIXME Hack to get around exclusive access to the sound device
#if OS_UNIX
ret = INFO::OK;
#else
ret = ERR::FAIL;
#endif
#endif // !OS_UNIX
}
return ret;
@ -142,8 +177,12 @@ void CSoundManager::SetActionGain(float gain)
ISoundItem* CSoundManager::LoadItem(const VfsPath& itemPath)
{
AL_CHECK
CSoundData* itemData = CSoundData::SoundDataFromFile(itemPath);
ISoundItem* answer = NULL;
AL_CHECK
if (itemData != NULL)
{
@ -198,10 +237,12 @@ void CSoundManager::IdleTask()
deadItems++;
}
}
AL_CHECK
if (m_CurrentTune)
m_CurrentTune->EnsurePlay();
if (m_CurrentEnvirons)
m_CurrentEnvirons->EnsurePlay();
AL_CHECK
}
void CSoundManager::DeleteItem(long itemNum)
@ -232,11 +273,6 @@ void CSoundManager::InitListener()
alDistanceModel(AL_EXPONENT_DISTANCE);
}
void CSoundManager::SetEnabled(bool doEnable)
{
m_Enabled = doEnable;
}
void CSoundManager::PlayActionItem(ISoundItem* anItem)
{
if (anItem)
@ -245,6 +281,7 @@ void CSoundManager::PlayActionItem(ISoundItem* anItem)
{
anItem->SetGain(m_Gain * m_ActionGain);
anItem->Play();
AL_CHECK
}
}
}
@ -255,6 +292,7 @@ void CSoundManager::PlayGroupItem(ISoundItem* anItem, ALfloat groupGain)
if (m_Enabled && (m_ActionGain > 0)) {
anItem->SetGain(m_Gain * groupGain);
anItem->Play();
AL_CHECK
}
}
}
@ -271,6 +309,7 @@ void CSoundManager::SetMusicEnabled (bool isEnabled)
void CSoundManager::SetMusicItem(ISoundItem* anItem)
{
AL_CHECK
if (m_CurrentTune)
{
m_CurrentTune->FadeAndDelete(3.00);
@ -291,6 +330,7 @@ void CSoundManager::SetMusicItem(ISoundItem* anItem)
anItem->StopAndDelete();
}
}
AL_CHECK
}
void CSoundManager::SetAmbientItem(ISoundItem* anItem)
@ -312,5 +352,8 @@ void CSoundManager::SetAmbientItem(ISoundItem* anItem)
m_CurrentEnvirons->FadeToIn(m_Gain * m_AmbientGain, 2.00);
}
}
AL_CHECK
}
#endif // CONFIG2_AUDIO

View File

@ -18,12 +18,18 @@
#ifndef INCLUDED_SOUNDMANAGER_H
#define INCLUDED_SOUNDMANAGER_H
#include "soundmanager/items/ISoundItem.h"
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "lib/file/vfs/vfs_path.h"
#include "soundmanager/items/ISoundItem.h"
#include <vector>
#include <map>
#define AL_CHECK CSoundManager::al_check(__func__, __LINE__);
typedef std::vector<ISoundItem*> ItemsList;
@ -45,6 +51,7 @@ protected:
long m_BufferSize;
int m_BufferCount;
bool m_MusicEnabled;
bool m_SoundEnabled;
public:
CSoundManager();
@ -53,8 +60,14 @@ public:
ISoundItem* LoadItem(const VfsPath& itemPath);
static void ScriptingInit();
static void CreateSoundManager();
static void SetEnabled(bool doEnable);
static void al_ReportError(ALenum err, const char* caller, int line);
static void al_check(const char* caller, int line);
void SetMusicEnabled (bool isEnabled);
void setSoundEnabled( bool enabled );
ISoundItem* ItemFromWAV(VfsPath& fname);
ISoundItem* ItemFromOgg(VfsPath& fname);
@ -78,14 +91,25 @@ public:
void SetAmbientGain(float gain);
void SetActionGain(float gain);
void SetEnabled(bool doEnable);
protected:
void InitListener();
virtual Status AlcInit();
};
#else // !CONFIG2_AUDIO
#define AL_CHECK
class CSoundManager
{
public:
static void ScriptingInit();
};
#endif // !CONFIG2_AUDIO
extern CSoundManager* g_SoundManager;
#endif // INCLUDED_SOUNDMANAGER_H

View File

@ -19,10 +19,11 @@
#include "OggData.h"
#include "soundmanager/SoundManager.h"
#include <wchar.h>
#include <iostream>
#if CONFIG2_AUDIO
#include "soundmanager/SoundManager.h"
#include "ps/Filesystem.h"
COggData::COggData()
{
@ -32,7 +33,6 @@ COggData::COggData()
COggData::~COggData()
{
alDeleteBuffers(m_BuffersUsed, m_Buffer);
ov_clear(&m_vf);
}
void COggData::SetFormatAndFreq(int form, ALsizei freq)
@ -41,25 +41,14 @@ void COggData::SetFormatAndFreq(int form, ALsizei freq)
m_Frequency = freq;
}
bool COggData::InitOggFile(const wchar_t* fileLoc)
bool COggData::InitOggFile(const VfsPath& itemPath)
{
int buffersToStart = g_SoundManager->GetBufferCount();
char nameH[300];
sprintf(nameH, "%ls", fileLoc);
FILE* f = fopen(nameH, "rb");
m_current_section = 0;
int err = ov_open_callbacks(f, &m_vf, NULL, 0, OV_CALLBACKS_DEFAULT);
if (err < 0)
{
fprintf(stderr,"Input does not appear to be an Ogg bitstream :%d :%d.\n", err, ferror(f));
return false;
}
m_FileName = CStrW(fileLoc);
int buffersToStart = g_SoundManager->GetBufferCount();
OpenOggNonstream( g_VFS, itemPath, ogg);
m_FileFinished = false;
SetFormatAndFreq((m_vf.vi->channels == 1)? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16 , (ALsizei)m_vf.vi->rate);
SetFormatAndFreq(ogg->Format(), ogg->SamplingRate() );
alGetError(); /* clear error */
alGenBuffers(buffersToStart, m_Buffer);
@ -96,8 +85,7 @@ bool COggData::IsFileFinished()
void COggData::ResetFile()
{
ov_time_seek(&m_vf, 0);
m_current_section = 0;
ogg->ResetFile();
m_FileFinished = false;
}
@ -110,32 +98,13 @@ int COggData::FetchDataIntoBuffer(int count, ALuint* buffers)
{
long bufferSize = g_SoundManager->GetBufferSize();
char* pcmout = new char[bufferSize + 5000];
u8* pcmout = new u8[bufferSize + 5000];
int buffersWritten = 0;
for (int i = 0; (i < count) && !m_FileFinished; i++)
{
char* readDest = pcmout;
long totalRet = 0;
while (totalRet < bufferSize)
{
long ret=ov_read(&m_vf,readDest, 4096,0,2,1, &m_current_section);
if (ret == 0)
{
m_FileFinished=true;
break;
}
else if (ret < 0)
{
/* error in the stream. Not a problem, just reporting it in
case we (the app) cares. In this case, we don't. */
}
else
{
totalRet += ret;
readDest += ret;
}
}
Status totalRet = ogg->GetNextChunk( pcmout, bufferSize);
m_FileFinished = ogg->atFileEOF();
if (totalRet > 0)
{
buffersWritten++;
@ -157,7 +126,5 @@ ALuint* COggData::GetBufferPtr()
return m_Buffer;
}
#endif // CONFIG2_AUDIO

View File

@ -18,9 +18,13 @@
#ifndef INCLUDED_OGGDATA_H
#define INCLUDED_OGGDATA_H
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "SoundData.h"
#include "lib/external_libraries/openal.h"
#include "vorbis/vorbisfile.h"
#include "ogg.h"
class COggData : public CSoundData
{
@ -31,7 +35,7 @@ public:
COggData();
virtual ~COggData();
virtual bool InitOggFile(const wchar_t* fileLoc);
virtual bool InitOggFile(const VfsPath& itemPath);
virtual bool IsFileFinished();
virtual bool IsOneShot();
@ -39,8 +43,8 @@ public:
virtual void ResetFile();
protected:
OggVorbis_File m_vf;
int m_current_section;
OggStreamPtr ogg;
// int m_current_section;
bool m_FileFinished;
bool m_OneShot;
ALuint m_Buffer[100];
@ -53,5 +57,5 @@ protected:
ALuint* GetBufferPtr();
};
#endif // CONFIG2_AUDIO
#endif // INCLUDED_OGGDATA_H

View File

@ -19,9 +19,9 @@
#include "SoundData.h"
#if CONFIG2_AUDIO
#include "OggData.h"
#include "lib/file/vfs/vfs_util.h"
#include "ps/Filesystem.h"
#include <iostream>
@ -96,15 +96,9 @@ CSoundData* CSoundData::SoundDataFromOgg(const VfsPath& itemPath)
CSoundData* answer = NULL;
COggData* oggAnswer = new COggData();
OsPath realPath;
Status ret = g_VFS->GetRealPath(itemPath, realPath);
if (ret == INFO::OK)
{
if (oggAnswer->InitOggFile(realPath.string().c_str()))
{
answer = oggAnswer;
}
}
if (oggAnswer->InitOggFile(itemPath))
answer = oggAnswer;
return answer;
}
@ -140,3 +134,5 @@ ALuint* CSoundData::GetBufferPtr()
return &m_ALBuffer;
}
#endif // CONFIG2_AUDIO

View File

@ -18,10 +18,12 @@
#ifndef INCLUDED_SOUNDDATA_H
#define INCLUDED_SOUNDDATA_H
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "lib/external_libraries/openal.h"
#include "lib/file/vfs/vfs_path.h"
#include "lib/os_path.h"
#include <string>
#include <map>
@ -61,4 +63,7 @@ protected:
};
#endif // CONFIG2_AUDIO
#endif // INCLUDED_SOUNDDATA_H

View File

@ -19,7 +19,10 @@
#include "CBufferItem.h"
#if CONFIG2_AUDIO
#include "soundmanager/data/SoundData.h"
#include "soundmanager/SoundManager.h"
#include <iostream>
@ -33,6 +36,8 @@ CBufferItem::CBufferItem(CSoundData* sndData)
CBufferItem::~CBufferItem()
{
AL_CHECK
Stop();
int num_processed;
alGetSourcei(m_ALSource, AL_BUFFERS_PROCESSED, &num_processed);
@ -41,7 +46,8 @@ CBufferItem::~CBufferItem()
{
ALuint* al_buf = new ALuint[num_processed];
alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
AL_CHECK
delete[] al_buf;
}
}
@ -67,7 +73,9 @@ bool CBufferItem::IdleTask()
{
ALuint al_buf;
alSourceUnqueueBuffers(m_ALSource, 1, &al_buf);
AL_CHECK
alSourceQueueBuffers(m_ALSource, 1, &al_buf);
AL_CHECK
}
}
@ -76,10 +84,12 @@ bool CBufferItem::IdleTask()
void CBufferItem::Attach(CSoundData* itemData)
{
AL_CHECK
if (itemData != NULL)
{
m_SoundData = itemData->IncrementCount();
alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(),(const ALuint *) m_SoundData->GetBufferPtr());
AL_CHECK
}
}
@ -88,3 +98,5 @@ void CBufferItem::SetLooping(bool loops)
m_Looping = loops;
}
#endif // CONFIG2_AUDIO

View File

@ -18,6 +18,10 @@
#ifndef INCLUDED_CBUFFERITEM_H
#define INCLUDED_CBUFFERITEM_H
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "CSoundBase.h"
class CBufferItem : public CSoundBase
@ -35,5 +39,7 @@ protected:
};
#endif // CONFIG2_AUDIO
#endif // INCLUDED_CBUFFERITEM_H

View File

@ -19,9 +19,12 @@
#include "CSoundBase.h"
#if CONFIG2_AUDIO
#include "lib/timer.h"
#include "soundmanager/SoundManager.h"
#include "soundmanager/data/SoundData.h"
#include "ps/CLogger.h"
#include <iostream>
@ -73,12 +76,17 @@ void CSoundBase::ResetFade()
void CSoundBase::SetGain(ALfloat gain)
{
AL_CHECK
alSourcef(m_ALSource, AL_GAIN, gain);
AL_CHECK
}
void CSoundBase::SetRollOff(ALfloat rolls)
{
alSourcef(m_ALSource, AL_ROLLOFF_FACTOR, rolls);
AL_CHECK
}
void CSoundBase::EnsurePlay()
@ -89,19 +97,25 @@ void CSoundBase::EnsurePlay()
void CSoundBase::SetCone(ALfloat innerCone, ALfloat outerCone, ALfloat coneGain)
{
alSourcef(m_ALSource, innerCone, AL_CONE_INNER_ANGLE);
alSourcef(m_ALSource, outerCone, AL_CONE_OUTER_ANGLE);
alSourcef(m_ALSource, coneGain, AL_CONE_OUTER_GAIN);
AL_CHECK
alSourcef(m_ALSource, AL_CONE_INNER_ANGLE, innerCone);
AL_CHECK
alSourcef(m_ALSource, AL_CONE_OUTER_ANGLE, outerCone);
AL_CHECK
alSourcef(m_ALSource, AL_CONE_OUTER_GAIN, coneGain);
AL_CHECK
}
void CSoundBase::SetPitch(ALfloat pitch)
{
alSourcef(m_ALSource, AL_PITCH, pitch);
AL_CHECK
}
void CSoundBase::SetDirection(const CVector3D& direction)
{
alSourcefv(m_ALSource, AL_DIRECTION, direction.GetFloatArray());
AL_CHECK
}
bool CSoundBase::InitOpenAL()
@ -109,11 +123,10 @@ bool CSoundBase::InitOpenAL()
alGetError(); /* clear error */
alGenSources(1, &m_ALSource);
long anErr = alGetError();
if (anErr != AL_NO_ERROR)
{
printf("- Error creating sources %ld !!\n", anErr);
}
else
AL_CHECK
if (anErr == AL_NO_ERROR)
{
ALfloat source0Pos[]={ -2.0, 0.0, 0.0};
ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
@ -123,6 +136,8 @@ bool CSoundBase::InitOpenAL()
alSourcefv(m_ALSource,AL_POSITION,source0Pos);
alSourcefv(m_ALSource,AL_VELOCITY,source0Vel);
alSourcei(m_ALSource,AL_LOOPING,AL_FALSE);
AL_CHECK
return true;
}
return false;
@ -132,6 +147,7 @@ bool CSoundBase::IsPlaying()
{
int proc_state;
alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
AL_CHECK
return (proc_state == AL_PLAYING);
}
@ -149,10 +165,12 @@ bool CSoundBase::IdleTask()
void CSoundBase::SetLocation (const CVector3D& position)
{
alSourcefv(m_ALSource,AL_POSITION, position.GetFloatArray());
AL_CHECK
}
bool CSoundBase::HandleFade()
{
AL_CHECK
if (m_StartFadeTime != 0)
{
double currTime = timer_Time();
@ -169,6 +187,8 @@ bool CSoundBase::HandleFade()
}
else
alSourcef(m_ALSource, AL_GAIN, curGain);
AL_CHECK
}
return true;
}
@ -182,6 +202,7 @@ void CSoundBase::SetLooping(bool loops)
{
m_Looping = loops;
alSourcei(m_ALSource, AL_LOOPING, loops ? AL_TRUE : AL_FALSE);
AL_CHECK
}
void CSoundBase::Play()
@ -189,6 +210,7 @@ void CSoundBase::Play()
m_ShouldBePlaying = true;
if (m_ALSource != 0)
alSourcePlay(m_ALSource);
AL_CHECK
}
void CSoundBase::PlayAndDelete()
@ -215,6 +237,7 @@ void CSoundBase::PlayLoop()
{
SetLooping(true);
Play();
AL_CHECK
}
}
@ -229,6 +252,7 @@ void CSoundBase::FadeToIn(ALfloat newVolume, double fadeDuration)
alGetSourcef(m_ALSource, AL_GAIN, &m_StartVolume);
m_EndVolume = newVolume;
}
AL_CHECK
}
void CSoundBase::PlayAsMusic()
@ -251,6 +275,8 @@ void CSoundBase::Stop()
alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
if (proc_state == AL_PLAYING)
alSourceStop(m_ALSource);
AL_CHECK
}
}
@ -274,3 +300,5 @@ void CSoundBase::SetNameFromPath(char* fileLoc)
m_Name->assign(anst.begin(), anst.end());
}
#endif // CONFIG2_AUDIO

View File

@ -18,12 +18,17 @@
#ifndef INCLUDED_CSOUNDBASE_H
#define INCLUDED_CSOUNDBASE_H
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "lib/external_libraries/openal.h"
#include "soundmanager/items/ISoundItem.h"
#include "soundmanager/data/SoundData.h"
#include <string>
class CSoundBase : public ISoundItem
{
protected:
@ -86,4 +91,7 @@ protected:
};
#endif // CONFIG2_AUDIO
#endif // INCLUDED_CSOUNDBASE_H

View File

@ -19,11 +19,13 @@
#include "CSoundItem.h"
#if CONFIG2_AUDIO
#include "soundmanager/data/SoundData.h"
#include "soundmanager/SoundManager.h"
#include <iostream>
CSoundItem::CSoundItem()
{
ResetVars();
@ -38,10 +40,12 @@ CSoundItem::CSoundItem(CSoundData* sndData)
CSoundItem::~CSoundItem()
{
AL_CHECK
ALuint al_buf;
Stop();
alSourceUnqueueBuffers(m_ALSource, 1, &al_buf);
AL_CHECK
}
bool CSoundItem::IdleTask()
@ -52,6 +56,7 @@ bool CSoundItem::IdleTask()
{
int proc_state;
alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
AL_CHECK
return (proc_state != AL_STOPPED);
}
return true;
@ -63,5 +68,10 @@ void CSoundItem::Attach(CSoundData* itemData)
{
m_SoundData = itemData->IncrementCount();
alSourcei(m_ALSource, AL_BUFFER, m_SoundData->GetBuffer());
AL_CHECK
}
}
#endif // CONFIG2_AUDIO

View File

@ -18,10 +18,13 @@
#ifndef INCLUDED_CSOUNDITEM_H
#define INCLUDED_CSOUNDITEM_H
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "CSoundBase.h"
#include "soundmanager/data/SoundData.h"
class CSoundItem : public CSoundBase
{
public:
@ -34,4 +37,7 @@ public:
};
#endif // CONFIG2_AUDIO
#endif // INCLUDED_CSOUNDITEM_H

View File

@ -19,7 +19,10 @@
#include "CStreamItem.h"
#if CONFIG2_AUDIO
#include "soundmanager/data/OggData.h"
#include "soundmanager/SoundManager.h"
#include <iostream>
@ -41,16 +44,20 @@ CStreamItem::~CStreamItem()
{
ALuint* al_buf = new ALuint[num_processed];
alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
AL_CHECK
delete[] al_buf;
}
}
bool CStreamItem::IdleTask()
{
AL_CHECK
HandleFade();
AL_CHECK
int proc_state;
alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
AL_CHECK
if (proc_state == AL_STOPPED)
{
@ -65,13 +72,16 @@ bool CStreamItem::IdleTask()
{
int num_processed;
alGetSourcei(m_ALSource, AL_BUFFERS_PROCESSED, &num_processed);
AL_CHECK
if (num_processed > 0)
{
ALuint* al_buf = new ALuint[num_processed];
alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
AL_CHECK
int didWrite = tmp->FetchDataIntoBuffer(num_processed, al_buf);
alSourceQueueBuffers(m_ALSource, didWrite, al_buf);
AL_CHECK
delete[] al_buf;
}
}
@ -89,6 +99,7 @@ void CStreamItem::Attach(CSoundData* itemData)
{
m_SoundData = itemData->IncrementCount();
alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), (const ALuint *)m_SoundData->GetBufferPtr());
AL_CHECK
}
}
@ -97,3 +108,5 @@ void CStreamItem::SetLooping(bool loops)
m_Looping = loops;
}
#endif // CONFIG2_AUDIO

View File

@ -18,6 +18,10 @@
#ifndef INCLUDED_CSTREAMITEM_H
#define INCLUDED_CSTREAMITEM_H
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "soundmanager/data/SoundData.h"
#include "CSoundBase.h"
@ -35,4 +39,7 @@ protected:
};
#endif // CONFIG2_AUDIO
#endif // INCLUDED_CSTREAMITEM_H

View File

@ -18,6 +18,10 @@
#ifndef INCLUDED_ISOUNDITEM_H
#define INCLUDED_ISOUNDITEM_H
#include "lib/config2.h"
#if CONFIG2_AUDIO
#include "lib/external_libraries/openal.h"
#include "maths/Vector3D.h"
@ -56,5 +60,7 @@ public:
virtual void SetRollOff(ALfloat gain) = 0;
};
#endif // CONFIG2_AUDIO
#endif // INCLUDED_ISOUNDITEM_H
#endif // INCLUDED_ISOUNDITEM_H

View File

@ -19,8 +19,10 @@
#include "AmbientSound.h"
#include "lib/config2.h"
#include "lib/utf8.h"
#include "maths/Vector3D.h"
#include "ps/CLogger.h"
#include "ps/Filesystem.h"
#include "soundmanager/SoundManager.h"
@ -32,31 +34,40 @@ JAmbientSound::JAmbientSound(const VfsPath& pathname) : m_FileName(pathname)
// start playing the sound, all ambient sounds loop
bool JAmbientSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd)
aSnd->PlayAsAmbient();
else
debug_printf(L"sound item could not be loaded to play: %ls\n", m_FileName.string().c_str());
#if CONFIG2_AUDIO
if ( g_SoundManager ) {
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd)
aSnd->PlayAsAmbient();
else
LOGERROR(L"sound item could not be loaded to play: %ls\n", m_FileName.string().c_str());
}
#endif // CONFIG2_AUDIO
return true;
}
// start playing the sound, all ambient sounds loop
bool JAmbientSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd)
aSnd->PlayAsAmbient();
else
debug_printf(L"sound item could not be loaded to loop: %ls\n", m_FileName.string().c_str());
#if CONFIG2_AUDIO
if ( g_SoundManager ) {
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd)
aSnd->PlayAsAmbient();
else
LOGERROR(L"sound item could not be loaded to loop: %ls\n", m_FileName.string().c_str());
}
#endif // CONFIG2_AUDIO
return true;
}
bool JAmbientSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
g_SoundManager->SetAmbientItem(0L);
#if CONFIG2_AUDIO
if ( g_SoundManager )
g_SoundManager->SetAmbientItem(0L);
#endif // CONFIG2_AUDIO
return true;
}
@ -90,11 +101,12 @@ JSBool JAmbientSound::Construct(JSContext* cx, uintN UNUSED(argc), jsval* vp)
CStrW filename;
if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename))
return JS_FALSE;
JAmbientSound* newObject = new JAmbientSound(filename);
newObject->m_EngineOwned = false;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
return JS_TRUE;
}

View File

@ -47,3 +47,4 @@ protected:
};
#endif // #ifndef INCLUDED_JAMBIENTSOUND

View File

@ -19,6 +19,7 @@
#include "MusicSound.h"
#include "lib/config2.h"
#include "lib/utf8.h"
#include "maths/Vector3D.h"
#include "ps/Filesystem.h"
@ -31,20 +32,26 @@ JMusicSound::JMusicSound(const VfsPath& pathname) : m_FileName(pathname)
bool JMusicSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd != NULL)
aSnd->PlayAsMusic();
#if CONFIG2_AUDIO
if ( g_SoundManager ) {
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd != NULL)
aSnd->PlayAsMusic();
}
#endif // CONFIG2_AUDIO
return true;
}
// request the sound be played until free() is called. returns immediately.
bool JMusicSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd != NULL)
aSnd->PlayAsMusic();
#if CONFIG2_AUDIO
if ( g_SoundManager ) {
ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
if (aSnd != NULL)
aSnd->PlayAsMusic();
}
#endif // CONFIG2_AUDIO
return true;
}
@ -75,6 +82,7 @@ JSBool JMusicSound::Construct(JSContext* cx, uintN UNUSED(argc), jsval* vp)
JMusicSound* newObject = new JMusicSound(filename);
newObject->m_EngineOwned = false;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
return JS_TRUE;
}

View File

@ -19,6 +19,7 @@
#include "Sound.h"
#include "lib/config2.h"
#include "lib/utf8.h"
#include "maths/Vector3D.h"
#include "ps/Filesystem.h"
@ -27,26 +28,36 @@
JSound::JSound(const VfsPath& pathname)
{
m_SndItem = g_SoundManager->LoadItem(pathname);
#if CONFIG2_AUDIO
if ( g_SoundManager )
m_SndItem = g_SoundManager->LoadItem(pathname);
#else // !CONFIG2_AUDIO
UNUSED2(pathname);
#endif // !CONFIG2_AUDIO
}
JSound::~JSound()
{
#if CONFIG2_AUDIO
if (m_SndItem)
{
m_SndItem->FadeAndDelete(0.2);
m_SndItem = 0;
}
#endif // CONFIG2_AUDIO
}
bool JSound::ClearSoundItem()
{
#if CONFIG2_AUDIO
m_SndItem = 0L;
#endif
return true;
}
bool JSound::SetGain(JSContext* cx, uintN UNUSED(argc), jsval* argv)
{
#if CONFIG2_AUDIO
if (! m_SndItem)
return false;
@ -54,12 +65,17 @@ bool JSound::SetGain(JSContext* cx, uintN UNUSED(argc), jsval* argv)
if (! ToPrimitive<float>(cx, argv[0], gain))
return false;
m_SndItem->SetGain(gain);
m_SndItem->SetGain(gain);
#else // !CONFIG2_AUDIO
UNUSED2(cx);
UNUSED2(argv);
#endif // !CONFIG2_AUDIO
return true;
}
bool JSound::SetPitch(JSContext* cx, uintN UNUSED(argc), jsval* argv)
{
#if CONFIG2_AUDIO
if (! m_SndItem)
return false;
@ -68,11 +84,16 @@ bool JSound::SetPitch(JSContext* cx, uintN UNUSED(argc), jsval* argv)
return false;
m_SndItem->SetPitch(pitch);
#else // !CONFIG2_AUDIO
UNUSED2(cx);
UNUSED2(argv);
#endif // CONFIG2_AUDIO
return true;
}
bool JSound::SetPosition(JSContext* cx, uintN argc, jsval* argv)
{
#if CONFIG2_AUDIO
if (! m_SndItem)
return false;
@ -84,13 +105,18 @@ bool JSound::SetPosition(JSContext* cx, uintN argc, jsval* argv)
return false;
m_SndItem->SetLocation(pos);
#else // !CONFIG2_AUDIO
UNUSED2(cx);
UNUSED2(argc);
UNUSED2(argv);
#endif // !CONFIG2_AUDIO
return true;
}
bool JSound::Fade(JSContext* cx, uintN UNUSED(argc), jsval* argv)
{
#if CONFIG2_AUDIO
if (! m_SndItem)
return false;
@ -104,38 +130,44 @@ bool JSound::Fade(JSContext* cx, uintN UNUSED(argc), jsval* argv)
m_SndItem->SetGain(initial_gain);
m_SndItem->FadeToIn(final_gain, length);
#else // !CONFIG2_AUDIO
UNUSED2(cx);
UNUSED2(argv);
#endif // !CONFIG2_AUDIO
return true;
}
bool JSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
#if CONFIG2_AUDIO
if (! m_SndItem)
return false;
m_SndItem->Play();
#endif // CONFIG2_AUDIO
return true;
}
bool JSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
#if CONFIG2_AUDIO
if (! m_SndItem)
return false;
m_SndItem->PlayLoop();
#endif // CONFIG2_AUDIO
return true;
}
bool JSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
#if CONFIG2_AUDIO
if (m_SndItem)
{
m_SndItem->FadeAndDelete(0.2);
m_SndItem = 0;
}
#endif // CONFIG2_AUDIO
return true;
}
@ -155,7 +187,11 @@ void JSound::ScriptingInit()
CStr JSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
#if CONFIG2_AUDIO
return "[object Sound: " + (m_SndItem ? m_SndItem->GetName() : "(null)") + "]";
#else // !CONFIG2_AUDIO
return "[object Sound: audio disabled]";
#endif // !CONFIG2_AUDIO
}
JSBool JSound::Construct(JSContext* cx, uintN UNUSED(argc), jsval* vp)
@ -169,6 +205,7 @@ JSBool JSound::Construct(JSContext* cx, uintN UNUSED(argc), jsval* vp)
JSound* newObject = new JSound(filename);
newObject->m_EngineOwned = false;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
return JS_TRUE;
}

View File

@ -32,6 +32,7 @@
#ifndef INCLUDED_JSOUND
#define INCLUDED_JSOUND
#include "lib/config2.h"
#include "scripting/ScriptableObject.h"
#include "soundmanager/items/ISoundItem.h"
@ -61,7 +62,10 @@ public:
static void ScriptingInit();
protected:
#if CONFIG2_AUDIO
ISoundItem* m_SndItem;
#endif
};
#endif // #ifndef INCLUDED_JSOUND

View File

@ -41,6 +41,7 @@
#include <algorithm>
extern CGame *g_Game;
#define PI 3.14126f
@ -94,10 +95,12 @@ CSoundGroup::~CSoundGroup()
ReleaseGroup();
}
#if CONFIG2_AUDIO
static float RandFloat(float min, float max)
{
return float(rand(min*100.0f, max*100.0f) / 100.0f);
}
#endif // CONFIG2_AUDIO
float CSoundGroup::RadiansOffCenter(const CVector3D& position, bool& onScreen, float& itemRollOff)
{
@ -155,43 +158,50 @@ float CSoundGroup::RadiansOffCenter(const CVector3D& position, bool& onScreen, f
void CSoundGroup::UploadPropertiesAndPlay(int theIndex, const CVector3D& position)
{
bool isOnscreen;
ALfloat initialRolllOff = 0.02f;
ALfloat itemRollOff = initialRolllOff;
#if CONFIG2_AUDIO
if ( g_SoundManager ) {
bool isOnscreen;
ALfloat initialRolllOff = 0.02f;
ALfloat itemRollOff = initialRolllOff;
float offSet = RadiansOffCenter(position, isOnscreen, itemRollOff);
float offSet = RadiansOffCenter(position, isOnscreen, itemRollOff);
if (isOnscreen || TestFlag(eDistanceless) || TestFlag(eOmnipresent))
{
if (snd_group.size() == 0)
Reload();
ISoundItem* hSound = snd_group[theIndex];
CVector3D origin = g_Game->GetView()->GetCamera()->GetOrientation().GetTranslation();
float sndDist = origin.Y;
if (!TestFlag(eOmnipresent))
if (isOnscreen || TestFlag(eDistanceless) || TestFlag(eOmnipresent))
{
hSound->SetLocation(CVector3D((sndDist * sin(offSet)), 0, sndDist * cos(offSet)));
if (TestFlag(eDistanceless))
hSound->SetRollOff(initialRolllOff);
if (snd_group.size() == 0)
Reload();
ISoundItem* hSound = snd_group[theIndex];
CVector3D origin = g_Game->GetView()->GetCamera()->GetOrientation().GetTranslation();
float sndDist = origin.Y;
if (!TestFlag(eOmnipresent))
{
hSound->SetLocation(CVector3D((sndDist * sin(offSet)), 0, sndDist * cos(offSet)));
if (TestFlag(eDistanceless))
hSound->SetRollOff(initialRolllOff);
else
hSound->SetRollOff(itemRollOff);
}
if (TestFlag(eRandPitch))
hSound->SetPitch(RandFloat(m_PitchLower, m_PitchUpper));
else
hSound->SetRollOff(itemRollOff);
hSound->SetPitch(m_Pitch);
ALfloat theGain = m_Gain;
if (TestFlag(eRandGain))
theGain = RandFloat(m_GainLower, m_GainUpper);
hSound->SetCone(m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
g_SoundManager->PlayGroupItem(hSound, theGain);
}
if (TestFlag(eRandPitch))
hSound->SetPitch(RandFloat(m_PitchLower, m_PitchUpper));
else
hSound->SetPitch(m_Pitch);
ALfloat theGain = m_Gain;
if (TestFlag(eRandGain))
theGain = RandFloat(m_GainLower, m_GainUpper);
hSound->SetCone(m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
g_SoundManager->PlayGroupItem(hSound, theGain);
}
#else // !CONFIG2_AUDIO
UNUSED2(theIndex);
UNUSED2(position);
#endif // !CONFIG2_AUDIO
}
@ -216,30 +226,36 @@ void CSoundGroup::Reload()
{
m_index = 0; // reset our index
#if CONFIG2_AUDIO
snd_group.clear();
for (size_t i = 0; i < filenames.size(); i++)
{
VfsPath thePath = m_filepath/filenames[i];
ISoundItem* temp = g_SoundManager->LoadItem(thePath);
if ( g_SoundManager ) {
for (size_t i = 0; i < filenames.size(); i++)
{
VfsPath thePath = m_filepath/filenames[i];
ISoundItem* temp = g_SoundManager->LoadItem(thePath);
if (temp == NULL)
HandleError(L"error loading sound", thePath, ERR::FAIL);
else
snd_group.push_back(temp);
if (temp == NULL)
HandleError(L"error loading sound", thePath, ERR::FAIL);
else
snd_group.push_back(temp);
}
if (TestFlag(eRandOrder))
random_shuffle(snd_group.begin(), snd_group.end());
}
if (TestFlag(eRandOrder))
random_shuffle(snd_group.begin(), snd_group.end());
#endif // CONFIG2_AUDIO
}
void CSoundGroup::ReleaseGroup()
{
#if CONFIG2_AUDIO
for (size_t i = 0; i < snd_group.size(); i++)
{
snd_group[i]->FadeAndDelete(0.2);
}
snd_group.clear();
#endif // CONFIG2_AUDIO
}
void CSoundGroup::Update(float UNUSED(TimeSinceLastFrame))
@ -386,3 +402,4 @@ bool CSoundGroup::LoadSoundGroup(const VfsPath& pathnameXML)
return true;
}

View File

@ -52,6 +52,7 @@ Example SoundGroup.xml
#ifndef INCLUDED_SOUNDGROUP_H
#define INCLUDED_SOUNDGROUP_H
#include "lib/config2.h"
#include "lib/file/vfs/vfs_path.h"
#include <vector>
@ -109,7 +110,9 @@ private:
size_t m_index; // index of the next sound to play
#if CONFIG2_AUDIO
std::vector<ISoundItem*> snd_group; // we store the handles so we can load now and play later
#endif
std::vector<std::wstring> filenames; // we need the filenames so we can reload when necessary.
VfsPath m_filepath; // the file path for the list of sound file resources
@ -134,3 +137,4 @@ private:
};
#endif //#ifndef INCLUDED_SOUNDGROUP_H

View File

@ -18,6 +18,7 @@
#include "SoundPlayer.h"
#include "lib/config2.h"
#include "lib/utf8.h"
#include "maths/Vector3D.h"
#include "ps/Filesystem.h"
@ -34,15 +35,20 @@ JSoundPlayer::~JSoundPlayer()
bool JSoundPlayer::StartMusic(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
g_SoundManager->SetMusicEnabled(true);
#if CONFIG2_AUDIO
if ( g_SoundManager )
g_SoundManager->SetMusicEnabled(true);
#endif
return true;
}
// request the sound be played until free() is called. returns immediately.
bool JSoundPlayer::StopMusic(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
{
g_SoundManager->SetMusicEnabled(false);
#if CONFIG2_AUDIO
if ( g_SoundManager )
g_SoundManager->SetMusicEnabled(false);
#endif
return true;
}
@ -61,7 +67,7 @@ JSBool JSoundPlayer::Construct(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval*
JSoundPlayer* newObject = new JSoundPlayer();
newObject->m_EngineOwned = false;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
return JS_TRUE;
}

View File

@ -56,3 +56,4 @@ protected:
};
#endif // #ifndef INCLUDED_JSOUNDPLAYER