diff --git a/stepmania/src/RageSound.cpp b/stepmania/src/RageSound.cpp index 792f159d09..a0f373ba9e 100644 --- a/stepmania/src/RageSound.cpp +++ b/stepmania/src/RageSound.cpp @@ -643,6 +643,12 @@ void RageSound::Stop() StopPlaying(); } +bool RageSound::Pause( bool bPause ) +{ + ASSERT( Sample ); + return SOUNDMAN->Pause( this, bPause ); +} + float RageSound::GetLengthSeconds() { diff --git a/stepmania/src/RageSound.h b/stepmania/src/RageSound.h index 43110aeeab..57fc5e34f2 100644 --- a/stepmania/src/RageSound.h +++ b/stepmania/src/RageSound.h @@ -108,6 +108,10 @@ public: RageSound *Play( const RageSoundParams *params=NULL ); void Stop(); + /* Cleanly pause or unpause the sound. If the sound wasn't already playing, + * return true and do nothing. */ + bool Pause( bool bPause ); + float GetLengthSeconds(); float GetPositionSeconds( bool *approximate=NULL, RageTimer *Timestamp=NULL ) const; int GetSampleRate() const; diff --git a/stepmania/src/RageSoundManager.cpp b/stepmania/src/RageSoundManager.cpp index 7f3c45db4b..70a0f73bf5 100644 --- a/stepmania/src/RageSoundManager.cpp +++ b/stepmania/src/RageSoundManager.cpp @@ -81,6 +81,14 @@ void RageSoundManager::StopMixing( RageSoundBase *snd ) driver->StopMixing(snd); } +bool RageSoundManager::Pause( RageSoundBase *snd, bool bPause ) +{ + if( driver == NULL ) + return false; + else + return driver->PauseMixing( snd, bPause ); +} + int64_t RageSoundManager::GetPosition( const RageSoundBase *snd ) const { if( driver == NULL ) diff --git a/stepmania/src/RageSoundManager.h b/stepmania/src/RageSoundManager.h index 487f467137..b3d1d3b172 100644 --- a/stepmania/src/RageSoundManager.h +++ b/stepmania/src/RageSoundManager.h @@ -32,6 +32,7 @@ public: void Update(float delta); void StartMixing( RageSoundBase *snd ); /* used by RageSound */ void StopMixing( RageSoundBase *snd ); /* used by RageSound */ + bool Pause( RageSoundBase *snd, bool bPause ); /* used by RageSound */ int64_t GetPosition( const RageSoundBase *snd ) const; /* used by RageSound */ void RegisterSound( RageSound *p ); /* used by RageSound */ void UnregisterSound( RageSound *p ); /* used by RageSound */ diff --git a/stepmania/src/arch/Sound/RageSoundDriver.h b/stepmania/src/arch/Sound/RageSoundDriver.h index 079e8502dd..01710b7499 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver.h +++ b/stepmania/src/arch/Sound/RageSoundDriver.h @@ -21,6 +21,13 @@ public: * snd was not actually being played, though it may print a warning. */ virtual void StopMixing( RageSoundBase *snd ) = 0; + /* Pause or unpause the given sound. If the sound was stopped (not paused), + * return false and do nothing; otherwise return true and pause or unpause + * the sound. Unlike StopMixing, pausing and unpause a sound will not lose + * any buffered sound (but will not release any resources associated with + * playing the sound, either). */ + virtual bool PauseMixing( RageSoundBase *snd, bool bStop ) = 0; + /* Get the current position of a given buffer, in the same units and time base * as passed to RageSound::GetPCM. */ virtual int64_t GetPosition( const RageSoundBase *snd ) const = 0; diff --git a/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.cpp b/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.cpp index 11f0961eaf..3ff0241b0e 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.cpp @@ -26,6 +26,7 @@ RageSound_Generic_Software::sound::sound() snd = NULL; state = STOPPED; available = true; + paused = false; } void RageSound_Generic_Software::sound::Allocate( int frames ) @@ -82,6 +83,9 @@ void RageSound_Generic_Software::Mix( int16_t *buf, int frames, int64_t frameno, continue; /* STOPPING or PLAYING. Read sound data. */ + if( sounds[i].paused ) + continue; + int got_frames = 0; int frames_left = frames; @@ -397,6 +401,27 @@ void RageSound_Generic_Software::StopMixing( RageSoundBase *snd ) } +bool RageSound_Generic_Software::PauseMixing( RageSoundBase *snd, bool bStop ) +{ + LockMut( m_Mutex ); + + /* Find the sound. */ + unsigned i; + for( i = 0; i < ARRAYSIZE(sounds); ++i ) + if( !sounds[i].available && sounds[i].snd == snd ) + break; + + if( i == ARRAYSIZE(sounds) ) + { + LOG->Trace( "not pausing a sound because it's not playing" ); + return false; + } + + sounds[i].paused = bStop; + + return true; +} + void RageSound_Generic_Software::StartDecodeThread() { ASSERT( !m_DecodeThread.IsCreated() ); diff --git a/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.h b/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.h index a446b4d3d2..cfb95d8978 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.h +++ b/stepmania/src/arch/Sound/RageSoundDriver_Generic_Software.h @@ -14,6 +14,7 @@ public: void StartMixing( RageSoundBase *snd ); /* used by RageSound */ void StopMixing( RageSoundBase *snd ); /* used by RageSound */ + bool PauseMixing( RageSoundBase *snd, bool bStop ); RageSound_Generic_Software(); virtual ~RageSound_Generic_Software(); @@ -107,6 +108,8 @@ private: /* If true, this sound is in STOPPED and available for use. */ bool available; + bool paused; + enum { STOPPED, /* idle */