1
0
forked from 0ad/0ad

SoundManager supports playlists

This was SVN commit r13368.
This commit is contained in:
stwf 2013-04-24 12:03:42 +00:00
parent 6115c3fc13
commit 71486bd57d
12 changed files with 152 additions and 23 deletions

View File

@ -88,23 +88,23 @@ Music.prototype.updateState = function()
break;
case this.states.PEACE:
this.switchMusic(this.getRandomTrack(this.tracks.PEACE), 3.0, true);
this.startPlayList(this.tracks.PEACE, 3.0, true);
break;
case this.states.BATTLE:
this.switchMusic(this.getRandomTrack(this.tracks.BATTLE), 2.0, true);
this.startPlayList(this.tracks.BATTLE, 2.0, true);
break;
case this.states.VICTORY:
this.switchMusic(this.getRandomTrack(this.tracks.VICTORY), 2.0, true);
this.startPlayList(this.tracks.VICTORY, 2.0, true);
break;
case this.states.DEFEAT:
this.switchMusic(this.getRandomTrack(this.tracks.DEFEAT), 2.0, true);
this.startPlayList(this.tracks.DEFEAT, 2.0, true);
break;
case this.states.DEFEAT_CUE:
this.switchMusic(this.getRandomTrack(this.tracks.DEFEAT_CUE), 2.0, false);
this.startPlayList(this.tracks.DEFEAT_CUE, 2.0, false);
this.setDelay(this.states.DEFEAT, 7000);
break;
@ -144,6 +144,23 @@ Music.prototype.getRandomTrack = function(tracks)
return tracks[getRandom(0, tracks.length-1)];
};
Music.prototype.startPlayList = function(tracks, fadeInPeriod, isLooping)
{
this.currentMusicList = new MusicList;
for (var i in tracks)
{
this.currentMusicList.addItem( this.RELATIVE_MUSIC_PATH + tracks[i] )
}
if (this.currentMusicList)
{
if (isLooping)
this.currentMusicList.loop();
else
this.currentMusicList.play();
}
};
Music.prototype.switchMusic = function(track, fadeInPeriod, isLooping)
{
this.currentMusic = new MusicSound(this.RELATIVE_MUSIC_PATH + track);

View File

@ -25,6 +25,7 @@
#include "soundmanager/items/CStreamItem.h"
#include "soundmanager/js/SoundPlayer.h"
#include "soundmanager/js/AmbientSound.h"
#include "soundmanager/js/MusicList.h"
#include "soundmanager/js/MusicSound.h"
#include "soundmanager/js/Sound.h"
#include "lib/external_libraries/libsdl.h"
@ -214,6 +215,7 @@ void CSoundManager::ScriptingInit()
JMusicSound::ScriptingInit();
JSound::ScriptingInit();
JSoundPlayer::ScriptingInit();
JMusicList::ScriptingInit();
}
@ -256,6 +258,7 @@ CSoundManager::CSoundManager()
m_Device = NULL;
m_Context = NULL;
m_Worker = NULL;
m_PlayListItems = NULL;
m_CurrentTune = 0;
m_Gain = 1;
m_MusicGain = 1;
@ -272,6 +275,11 @@ CSoundManager::CSoundManager()
m_DistressTime = 0;
m_DistressErrCount = 0;
m_PlayingPlaylist = false;
m_LoopingPlaylist = false;
m_RunningPlaylist = false;
m_PlaylistGap = 0;
m_Enabled = false;
AlcInit();
@ -279,6 +287,8 @@ CSoundManager::CSoundManager()
{
InitListener();
m_PlayListItems = new PlayList;
m_Worker = new CSoundManagerWorker();
m_Worker->SetEnabled( true );
}
@ -298,6 +308,9 @@ CSoundManager::~CSoundManager()
}
AL_CHECK
if ( m_PlayListItems )
delete m_PlayListItems;
if ( m_ALSourceBuffer != NULL )
delete[] m_ALSourceBuffer;
@ -453,6 +466,42 @@ long CSoundManager::GetBufferSize()
return m_BufferSize;
}
void CSoundManager::AddPlayListItem( VfsPath* itemPath)
{
m_PlayListItems->push_back( *itemPath );
}
void CSoundManager::ClearPlayListItems()
{
if ( m_PlayingPlaylist )
SetMusicItem( NULL );
m_PlayingPlaylist = false;
m_LoopingPlaylist = false;
m_RunningPlaylist = false;
m_PlayListItems->clear();
}
void CSoundManager::StartPlayList( bool doLoop )
{
if ( m_PlayListItems->size() > 0 )
{
m_PlayingPlaylist = true;
m_LoopingPlaylist = doLoop;
m_RunningPlaylist = false;
ISoundItem* aSnd = g_SoundManager->LoadItem( (m_PlayListItems->at( 0 )) );
if ( aSnd )
SetMusicItem( aSnd );
else
{
SetMusicItem( NULL );
}
}
}
void CSoundManager::SetMasterGain(float gain)
{
if ( m_Enabled )
@ -527,7 +576,35 @@ void CSoundManager::IdleTask()
if ( m_Enabled )
{
if (m_CurrentTune)
{
m_CurrentTune->EnsurePlay();
if ( m_PlayingPlaylist && m_RunningPlaylist )
{
if ( m_CurrentTune->Finished() )
{
if ( m_PlaylistGap == 0 )
{
m_PlaylistGap = timer_Time() + 15;
}
else if ( m_PlaylistGap < timer_Time() )
{
m_PlaylistGap = 0;
PlayList::iterator it = find (m_PlayListItems->begin(), m_PlayListItems->end(), *(m_CurrentTune->GetName()) );
it++;
Path nextPath;
if ( it == m_PlayListItems->end() )
nextPath = m_PlayListItems->at( 0 );
else
nextPath = *it;
ISoundItem* aSnd = g_SoundManager->LoadItem( nextPath );
if ( aSnd )
SetMusicItem( aSnd );
}
}
}
}
if (m_CurrentEnvirons)
m_CurrentEnvirons->EnsurePlay();
@ -614,7 +691,15 @@ void CSoundManager::SetMusicItem(ISoundItem* anItem)
{
m_CurrentTune = anItem;
m_CurrentTune->SetGain(0);
m_CurrentTune->PlayLoop();
if ( m_PlayingPlaylist )
{
m_RunningPlaylist = true;
m_CurrentTune->Play();
}
else
m_CurrentTune->PlayLoop();
m_CurrentTune->FadeToIn( m_MusicGain, 1.00);
}
else

View File

@ -34,6 +34,7 @@
#define AL_CHECK CSoundManager::al_check(__func__, __LINE__);
typedef std::vector<VfsPath> PlayList;
typedef std::vector<ISoundItem*> ItemsList;
typedef std::map<entity_id_t, ISoundItem*> ItemsMap;
@ -58,6 +59,7 @@ protected:
ISoundItem* m_CurrentEnvirons;
CSoundManagerWorker* m_Worker;
CMutex m_DistressMutex;
PlayList* m_PlayListItems;
float m_Gain;
float m_MusicGain;
@ -72,7 +74,11 @@ protected:
bool m_MusicPaused;
bool m_AmbientPaused;
bool m_ActionPaused;
bool m_RunningPlaylist;
bool m_PlayingPlaylist;
bool m_LoopingPlaylist;
long m_PlaylistGap;
long m_DistressErrCount;
long m_DistressTime;
@ -86,6 +92,10 @@ public:
ISoundItem* ItemForData(CSoundData* itemData);
ISoundItem* ItemForEntity( entity_id_t source, CSoundData* sndData);
void ClearPlayListItems();
void StartPlayList( bool doLoop );
void AddPlayListItem( VfsPath* itemPath);
static void ScriptingInit();
static void CreateSoundManager();
static void SetEnabled(bool doEnable);

View File

@ -57,7 +57,7 @@ void CSoundData::ReleaseSoundData(CSoundData* theData)
if (theData->DecrementCount())
{
if ((itemFind = CSoundData::sSoundData->find( *theData->GetFileName() )) != sSoundData->end())
if ((itemFind = CSoundData::sSoundData->find( theData->GetFileName()->string() )) != sSoundData->end())
{
CSoundData::sSoundData->erase(itemFind);
}
@ -74,14 +74,13 @@ CSoundData* CSoundData::SoundDataFromFile(const VfsPath& itemPath)
DataMap::iterator itemFind;
CSoundData* answer = NULL;
if ((itemFind = CSoundData::sSoundData->find(itemPath.string())) != sSoundData->end())
{
answer = itemFind->second;
}
else
{
if (fExt == ".ogg")
if (fExt == ".ogg")
answer = SoundDataFromOgg(itemPath);
if (answer && answer->IsOneShot())
@ -123,7 +122,7 @@ int CSoundData::GetBufferCount()
return 1;
}
CStrW* CSoundData::GetFileName()
Path* CSoundData::GetFileName()
{
return m_FileName;
}
@ -132,7 +131,7 @@ void CSoundData::SetFileName(const Path& aName)
{
delete m_FileName;
m_FileName = new CStrW( aName.string() );
m_FileName = new Path( aName );
}
CSoundData* CSoundData::IncrementCount()

View File

@ -50,7 +50,7 @@ public:
virtual unsigned int GetBuffer();
virtual int GetBufferCount();
virtual CStrW* GetFileName();
virtual Path* GetFileName();
virtual void SetFileName(const Path& aName);
virtual unsigned int* GetBufferPtr();
@ -60,7 +60,7 @@ protected:
unsigned int m_ALBuffer;
int m_RetentionCount;
CStrW* m_FileName;
Path* m_FileName;
};

View File

@ -76,6 +76,7 @@ bool CBufferItem::IdleTask()
int proc_state;
alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
AL_CHECK
m_ShouldBePlaying = (proc_state != AL_STOPPED);
return (proc_state != AL_STOPPED);
}

View File

@ -74,7 +74,8 @@ void CSoundBase::ResetVars()
m_EndFadeTime = 0;
m_StartVolume = 0;
m_EndVolume = 0;
m_ShouldBePlaying = false;
m_IsPaused = false;
ResetFade();
}
@ -84,10 +85,13 @@ void CSoundBase::ResetFade()
m_EndFadeTime = 0;
m_StartVolume = 0;
m_EndVolume = 0;
m_ShouldBePlaying = false;
m_PauseAfterFade = false;
}
bool CSoundBase::Finished()
{
return !m_ShouldBePlaying && !IsPlaying();
}
bool CSoundBase::InitOpenAL()
{
@ -141,7 +145,7 @@ void CSoundBase::SetRollOff(ALfloat rolls)
void CSoundBase::EnsurePlay()
{
if (m_ShouldBePlaying && !IsPlaying())
if (m_ShouldBePlaying && !m_IsPaused && !IsPlaying())
Play();
}
@ -275,6 +279,7 @@ void CSoundBase::Play()
CScopeLock lock(m_ItemMutex);
m_ShouldBePlaying = true;
m_IsPaused = false;
AL_CHECK
if (m_ALSource != 0)
{
@ -366,7 +371,7 @@ void CSoundBase::Stop()
}
}
CStrW* CSoundBase::GetName()
Path* CSoundBase::GetName()
{
if ( m_SoundData )
return m_SoundData->GetFileName();
@ -378,6 +383,7 @@ void CSoundBase::Pause()
{
if (m_ALSource != 0)
{
m_IsPaused = true;
alSourcePause(m_ALSource);
AL_CHECK
}

View File

@ -38,7 +38,8 @@ protected:
bool m_Looping;
bool m_ShouldBePlaying;
bool m_PauseAfterFade;
bool m_IsPaused;
double m_StartFadeTime;
double m_EndFadeTime;
@ -63,7 +64,8 @@ public:
void SetLastPlay(bool last);
void ReleaseOpenAL();
bool IsFading();
bool Finished();
void Play();
void PlayAndDelete();
void PlayLoop();
@ -83,7 +85,7 @@ public:
void Pause();
void Resume();
CStrW* GetName();
Path* GetName();
virtual void SetLooping(bool loops);
virtual bool IdleTask();

View File

@ -57,6 +57,7 @@ bool CSoundItem::IdleTask()
int proc_state;
alGetSourcei(m_ALSource, AL_SOURCE_STATE, &proc_state);
AL_CHECK
m_ShouldBePlaying = (proc_state != AL_STOPPED);
return (proc_state != AL_STOPPED);
}
return true;

View File

@ -103,6 +103,12 @@ bool CStreamItem::IdleTask()
{
theData->ResetFile();
}
else
{
int num_processed;
alGetSourcei(m_ALSource, AL_BUFFERS_QUEUED, &num_processed);
m_ShouldBePlaying = ( num_processed == 0 );
}
}
}
AL_CHECK

View File

@ -37,10 +37,11 @@ public:
virtual bool IsPlaying() = 0;
virtual CStrW* GetName() = 0;
virtual Path* GetName() = 0;
virtual bool IdleTask() = 0;
virtual bool IsFading() = 0;
virtual bool Finished() = 0;
virtual void Play() = 0;
virtual void Stop() = 0;

View File

@ -189,7 +189,8 @@ 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()->ToUTF8() : "(null)") + "]";
CStrW titleString( m_SndItem->GetName()->string() );
return "[object Sound: " + (m_SndItem ? titleString.ToUTF8() : "(null)") + "]";
#else // !CONFIG2_AUDIO
return "[object Sound: audio disabled]";
#endif // !CONFIG2_AUDIO