diff --git a/stepmania/src/RageSoundManager.cpp b/stepmania/src/RageSoundManager.cpp index f097574b07..6ecb6b981d 100644 --- a/stepmania/src/RageSoundManager.cpp +++ b/stepmania/src/RageSoundManager.cpp @@ -32,6 +32,8 @@ RageSoundManager::RageSoundManager(CString drivers) SOUNDMAN = NULL; throw; } + + pos_map_queue.reserve( 1024 ); } RageSoundManager::~RageSoundManager() @@ -75,6 +77,9 @@ int64_t RageSoundManager::GetPosition( const RageSoundBase *snd ) const void RageSoundManager::Update(float delta) { LockMut(lock); + + FlushPosMapQueue(); + while(!sounds_to_delete.empty()) { delete *sounds_to_delete.begin(); @@ -105,6 +110,42 @@ void RageSoundManager::UnregisterSound( RageSound *p ) all_sounds.erase( p ); } +void RageSoundManager::CommitPlayingPosition( int ID, int64_t frameno, int pos, int got_frames ) +{ + /* This can be called from realtime threads; don't lock any mutexes. */ + queued_pos_map_t p; + p.ID = ID; + p.frameno = frameno; + p.pos = pos; + p.got_frames = got_frames; + + pos_map_queue.write( &p, 1 ); +} + +void RageSoundManager::FlushPosMapQueue() +{ + LockMut(SOUNDMAN->lock); + queued_pos_map_t p; + + while( pos_map_queue.read( &p, 1 ) ) + { + /* Find the sound with p.ID. */ + set::iterator it; + for( it = all_sounds.begin(); it != all_sounds.end(); ++it ) + if( (*it)->GetID() == p.ID ) + break; + + /* If we can't find the ID, the sound was probably deleted before we got here. */ + if( it == all_sounds.end() ) + { + LOG->Trace("ignored unknown (stale?) commit ID %i", p.ID); + continue; + } + + (*it)->CommitPlayingPosition( p.frameno, p.pos, p.got_frames ); + } +} + float RageSoundManager::GetPlayLatency() const { return driver->GetPlayLatency(); diff --git a/stepmania/src/RageSoundManager.h b/stepmania/src/RageSoundManager.h index c859fa6fe6..99c58510a4 100644 --- a/stepmania/src/RageSoundManager.h +++ b/stepmania/src/RageSoundManager.h @@ -5,6 +5,7 @@ #include #include "SDL_utils.h" #include "RageThreads.h" +#include "RageUtil_CircularBuffer.h" class RageSound; class RageSoundBase; @@ -24,6 +25,13 @@ class RageSoundManager /* Prefs: */ float MixVolume; + struct queued_pos_map_t + { + int ID, pos, got_frames; + int64_t frameno; + }; + + CircBuf pos_map_queue; public: RageMutex lock; @@ -40,6 +48,8 @@ public: int64_t GetPosition( const RageSoundBase *snd ) const; /* used by RageSound */ int RegisterSound( RageSound *p ); /* used by RageSound */ void UnregisterSound( RageSound *p ); /* used by RageSound */ + void CommitPlayingPosition( int ID, int64_t frameno, int pos, int got_bytes ); /* used by drivers */ + void FlushPosMapQueue(); /* used by RageSound */ float GetPlayLatency() const; int GetDriverSampleRate( int rate ) const; const set &GetPlayingSounds() const { return playing_sounds; }