Pass RageSoundParams to Play() (or SetParams). This should help fix

the long-standing ambiguity of "what happens if parameters are changed
for a second copy of a sound when a first is still playing".
This commit is contained in:
Glenn Maynard
2004-02-28 02:09:46 +00:00
parent 71d1380951
commit be03ed1c21
8 changed files with 96 additions and 121 deletions
+22 -67
View File
@@ -60,7 +60,7 @@ RageSoundParams::RageSoundParams():
m_Balance = 0; // center
speed_input_samples = speed_output_samples = 1;
AccurateSync = false;
StopMode = RageSoundParams::M_STOP;
StopMode = M_AUTO;
}
RageSound::RageSound()
@@ -153,13 +153,6 @@ bool RageSound::Load(CString sSoundFilePath, int precache)
m_sFilePath = sSoundFilePath;
position = 0;
// Check for "loop" hint
if( m_sFilePath.Find("loop") != -1 )
SetStopMode( RageSoundParams::M_LOOP );
else
SetStopMode( RageSoundParams::M_STOP );
CString error;
Sample = SoundReader_FileReader::OpenFile( m_sFilePath, error );
if( Sample == NULL )
@@ -192,20 +185,6 @@ bool RageSound::Load(CString sSoundFilePath, int precache)
return true;
}
void RageSound::SetStartSeconds( float secs )
{
ASSERT(!playing);
m_Param.m_StartSecond = secs;
}
void RageSound::SetLengthSeconds(float secs)
{
RAGE_ASSERT_M( secs == -1 || secs >= 0, ssprintf("%f",secs) );
ASSERT(!playing);
m_Param.m_LengthSeconds = secs;
}
/* Read data at the rate we're playing it. We only do this to smooth out the rate
* we read data; the sound thread will always read more if it's needed.
*
@@ -522,8 +501,8 @@ void RageSound::StartPlaying()
LockMut(SOUNDMAN->lock);
// If no volume is set, use the default.
if( GetVolume() == -1 )
SetVolume( SOUNDMAN->GetMixVolume() );
if( m_Param.m_Volume == -1 )
m_Param.m_Volume = SOUNDMAN->GetMixVolume();
stopped_position = -1;
@@ -560,9 +539,9 @@ void RageSound::StopPlaying()
pos_map.clear();
}
RageSound *RageSound::Play()
RageSound *RageSound::Play( const RageSoundParams *params )
{
return SOUNDMAN->PlaySound(*this);
return SOUNDMAN->PlaySound( *this, params );
}
void RageSound::Stop()
@@ -788,48 +767,18 @@ bool RageSound::SetPositionFrames( int frames )
return true;
}
void RageSound::SetStopMode( RageSoundParams::StopMode_t m )
void RageSoundParams::SetPlaybackRate( float NewSpeed )
{
m_Param.StopMode = m;
}
RageSoundParams::StopMode_t RageSound::GetStopMode() const
{
return m_Param.StopMode;
}
void RageSound::SetAccurateSync( bool yes )
{
m_Param.AccurateSync = yes;
}
void RageSound::SetPlaybackRate( float NewSpeed )
{
LockMut(SOUNDMAN->lock);
if(GetPlaybackRate() == NewSpeed)
return;
if( NewSpeed == 1.00f )
{
m_Param.speed_input_samples = 1; m_Param.speed_output_samples = 1;
speed_input_samples = 1; speed_output_samples = 1;
} else {
/* Approximate it to the nearest tenth. */
m_Param.speed_input_samples = int( roundf(NewSpeed * 10) );
m_Param.speed_output_samples = 10;
speed_input_samples = int( roundf(NewSpeed * 10) );
speed_output_samples = 10;
}
}
void RageSound::SetFadeLength( float fSeconds )
{
m_Param.m_FadeLength = fSeconds;
}
void RageSound::SetVolume( float fVolume )
{
m_Param.m_Volume = fVolume;
}
float RageSound::GetVolume() const
{
return m_Param.m_Volume;
@@ -840,19 +789,25 @@ float RageSound::GetPlaybackRate() const
return float(m_Param.speed_input_samples) / m_Param.speed_output_samples;
}
void RageSound::SetStartTime( const RageTimer &tm )
{
m_Param.StartTime = tm;
}
RageTimer RageSound::GetStartTime() const
{
return m_Param.StartTime;
}
void RageSound::SetBalance( float f )
void RageSound::SetParams( const RageSoundParams &p )
{
m_Param.m_Balance = f;
m_Param = p;
}
RageSoundParams::StopMode_t RageSound::GetStopMode() const
{
if( m_Param.StopMode != RageSoundParams::M_AUTO )
return m_Param.StopMode;
if( m_sFilePath.Find("loop") != -1 )
return RageSoundParams::M_LOOP;
else
return RageSoundParams::M_STOP;
}
/*
+12 -16
View File
@@ -32,6 +32,7 @@ struct RageSoundParams
/* Amount of time to fade out at the end. */
float m_FadeLength;
void SetNoFade() { m_FadeLength = 0; }
float m_Volume;
@@ -41,6 +42,7 @@ struct RageSoundParams
/* Number of samples input and output when changing speed. Currently,
* this is either 1/1, 5/4 or 4/5. */
int speed_input_samples, speed_output_samples;
void SetPlaybackRate( float fScale );
bool AccurateSync;
@@ -52,7 +54,10 @@ struct RageSoundParams
* M_LOOP restarts.
* M_CONTINUE feeds silence, which is useful to continue timing longer than the actual sound. */
enum StopMode_t {
M_STOP, M_LOOP, M_CONTINUE
M_STOP, /* stop when finished */
M_LOOP, /* loop */
M_CONTINUE, /* keep playing silence */
M_AUTO /* obey filename hints */
} StopMode;
};
@@ -82,37 +87,27 @@ public:
bool Load(CString fn, int precache = 2);
void Unload();
void SetStopMode( RageSoundParams::StopMode_t m );
RageSoundParams::StopMode_t GetStopMode() const;
void SetStartSeconds(float secs = 0); /* default = beginning */
void SetLengthSeconds(float secs = -1); /* default = no length limit */
void StartPlaying();
void StopPlaying();
CString GetError() const { return error; }
bool Error() const { return !error.empty(); }
RageSound *Play();
RageSound *Play( const RageSoundParams *params=NULL );
void Stop();
float GetLengthSeconds();
float GetPositionSeconds( bool *approximate=NULL, RageTimer *Timestamp=NULL ) const;
int GetSampleRate() const;
bool SetPositionSeconds( float fSeconds = -1);
bool SetPositionSeconds( float fSeconds );
CString GetLoadedFilePath() const { return m_sFilePath; }
bool IsPlaying() const { return playing; }
void SetAccurateSync( bool yes=true );
void SetPlaybackRate( float fScale );
void SetFadeLength( float fSeconds );
void SetVolume( float fVolume );
float GetVolume() const;
void SetNoFade() { SetFadeLength(0); }
float GetPlaybackRate() const;
void SetStartTime( const RageTimer &tm );
RageTimer GetStartTime() const;
void SetBalance( float f );
float GetVolume() const;
void SetParams( const RageSoundParams &p );
const RageSoundParams &GetParams() const { return m_Param; }
private:
/* If we were copied from another RageSound, this will point to it; otherwise
@@ -164,6 +159,7 @@ private:
int GetData(char *buffer, int size);
void Fail(CString reason);
int Bytes_Available() const;
RageSoundParams::StopMode_t GetStopMode() const; /* resolves M_AUTO */
static void RateChange(char *buf, int &cnt, int speed_input_samples, int speed_output_samples, int channels);
+6 -2
View File
@@ -98,7 +98,7 @@ int RageSoundManager::GetDriverSampleRate( int rate ) const
return driver->GetSampleRate( rate );
}
RageSound *RageSoundManager::PlaySound(RageSound &snd)
RageSound *RageSoundManager::PlaySound( RageSound &snd, const RageSoundParams *params )
{
LockMut(lock);
@@ -113,8 +113,12 @@ RageSound *RageSoundManager::PlaySound(RageSound &snd)
owned_sounds.insert(sound_to_play);
}
if( params )
sound_to_play->SetParams( *params );
// Move to the start position.
sound_to_play->SetPositionSeconds();
sound_to_play->SetPositionSeconds( sound_to_play->GetParams().m_StartSecond );
sound_to_play->StartPlaying();
return sound_to_play;
+2 -1
View File
@@ -9,6 +9,7 @@
class RageSound;
class RageSoundBase;
class RageSoundDriver;
struct RageSoundParams;
class RageSoundManager
{
@@ -43,7 +44,7 @@ public:
void PlayOnce( CString sPath );
RageSound *PlaySound(RageSound &snd);
RageSound *PlaySound( RageSound &snd, const RageSoundParams *params );
void StopPlayingSound(RageSound &snd);
/* A list of all sounds that currently exist. RageSound adds and removes
+7 -11
View File
@@ -133,19 +133,15 @@ void StartPlayingMusic( const RageTimer &when, const MusicToPlay &ToPlay, MusicP
Playing.m_Music->Load( ToPlay.file, false );
RageSoundParams p;
p.m_StartSecond = ToPlay.start_sec;
p.m_LengthSeconds = ToPlay.length_sec;
p.m_FadeLength = ToPlay.fade_len;
p.StartTime = when;
if( ToPlay.force_loop )
Playing.m_Music->SetStopMode( RageSound::M_LOOP );
p.StopMode = RageSoundParams::M_LOOP;
Playing.m_Music->SetStartSeconds( ToPlay.start_sec );
if( ToPlay.length_sec == -1 )
Playing.m_Music->SetLengthSeconds();
else
Playing.m_Music->SetLengthSeconds( ToPlay.length_sec );
Playing.m_Music->SetFadeLength( ToPlay.fade_len );
Playing.m_Music->SetPositionSeconds();
Playing.m_Music->SetStartTime( when );
Playing.m_Music->SetPositionSeconds( p.m_StartSecond );
Playing.m_Music->StartPlaying();
}
+15 -10
View File
@@ -373,8 +373,6 @@ ScreenEdit::ScreenEdit( CString sName ) : Screen( sName )
m_soundMusic.Load(m_pSong->GetMusicPath());
m_soundMusic.SetAccurateSync(true);
m_soundMusic.SetStopMode( RageSoundParams::M_CONTINUE );
m_soundAssistTick.Load( THEME->GetPathToS("ScreenEdit assist tick") );
}
@@ -417,8 +415,9 @@ void ScreenEdit::PlayTicks()
fSecondsUntil /= m_soundMusic.GetPlaybackRate(); /* 2x music rate means the time until the tick is halved */
RageTimer when = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)TICK_EARLY_SECONDS);
m_soundAssistTick.SetStartTime( when );
m_soundAssistTick.Play();
RageSoundParams p;
p.StartTime = when;
m_soundAssistTick.Play( &p );
}
}
@@ -1941,9 +1940,12 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
m_Foreground.LoadFromSong( m_pSong );
}
m_soundMusic.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
m_soundMusic.SetPositionSeconds( fStartSeconds );
m_soundMusic.StartPlaying();
RageSoundParams p;
p.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
p.m_StartSecond = fStartSeconds;
p.AccurateSync = true;
p.StopMode = RageSoundParams::M_CONTINUE;
m_soundMusic.Play( &p );
}
break;
case record:
@@ -1970,9 +1972,12 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
float fStartSeconds = m_pSong->GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat);
LOG->Trace( "Starting playback at %f", fStartSeconds );
m_soundMusic.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
m_soundMusic.SetPositionSeconds( fStartSeconds );
m_soundMusic.StartPlaying();
RageSoundParams p;
p.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
p.m_StartSecond = fStartSeconds;
p.AccurateSync = true;
p.StopMode = RageSoundParams::M_CONTINUE;
m_soundMusic.Play( &p );
}
break;
case insert_and_shift:
+10 -8
View File
@@ -961,7 +961,6 @@ void ScreenGameplay::LoadNextSong()
m_soundMusic = new RageSound;
m_soundMusic->SetAccurateSync();
m_soundMusic->Load( GAMESTATE->m_pCurSong->GetMusicPath() );
/* Set up song-specific graphics. */
@@ -1017,12 +1016,14 @@ float ScreenGameplay::StartPlayingSong(float MinTimeToNotes, float MinTimeToMusi
fStartSecond = min(fStartSecond, -MinTimeToMusic);
ASSERT( m_soundMusic );
m_soundMusic->SetPositionSeconds( fStartSecond );
m_soundMusic->SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
/* Keep the music playing after it's finished; we'll stop it. */
m_soundMusic->SetStopMode( RageSoundParams::M_CONTINUE );
m_soundMusic->StartPlaying();
RageSoundParams p;
p.AccurateSync = true;
p.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
p.StopMode = RageSoundParams::M_CONTINUE;
p.m_StartSecond = fStartSecond;
m_soundMusic->Play( &p );
SOUND->TakeOverSound( m_soundMusic, &GAMESTATE->m_pCurSong->m_Timing );
m_soundMusic = NULL; // SOUND owns it now
@@ -1068,8 +1069,9 @@ void ScreenGameplay::PlayTicks()
fSecondsUntil /= GAMESTATE->m_SongOptions.m_fMusicRate; /* 2x music rate means the time until the tick is halved */
RageTimer when = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)TICK_EARLY_SECONDS);
m_soundAssistTick.SetStartTime( when );
m_soundAssistTick.Play();
RageSoundParams p;
p.StartTime = when;
m_soundAssistTick.Play( &p );
}
}
+22 -6
View File
@@ -57,7 +57,10 @@ ScreenTestSound::ScreenTestSound( CString sClassName ) : Screen( sClassName )
//s[0].s.SetStartSeconds(45);
//s[0].s.SetPositionSeconds();
// s[4].s.SetLengthSeconds(1);
s[0].s.SetPlaybackRate(1.20f);
RageSoundParams p;
p.SetPlaybackRate( 1.20f );
s[0].s.SetParams( p );
//s[0].s.SetStopMode(RageSound::M_LOOP);
//s[0].s.Play();
@@ -92,9 +95,9 @@ void ScreenTestSound::UpdateText(int n)
"%s",
n+1, fn.c_str(),
s[n].s.IsPlaying()? "Playing":"Stopped",
s[n].s.GetStopMode() == RageSoundParams::M_STOP?
s[n].s.GetParams().StopMode == RageSoundParams::M_STOP?
"Stop when finished":
s[n].s.GetStopMode() == RageSoundParams::M_CONTINUE?
s[n].s.GetParams().StopMode == RageSoundParams::M_CONTINUE?
"Continue until stopped":
"Loop",
pos.size()? pos.c_str(): "none playing",
@@ -130,13 +133,26 @@ void ScreenTestSound::Input( const DeviceInput& DeviceI, const InputEventType ty
s[selected].s.Stop();
break;
case 'l':
s[selected].s.SetStopMode(RageSoundParams::M_LOOP);
{
RageSoundParams p = s[selected].s.GetParams();
p.StopMode = RageSoundParams::M_LOOP;
s[selected].s.SetParams( p );
}
break;
case 'a':
s[selected].s.SetStopMode(RageSoundParams::M_STOP);
{
RageSoundParams p = s[selected].s.GetParams();
p.StopMode = RageSoundParams::M_STOP;
s[selected].s.SetParams( p );
}
break;
case 'c':
s[selected].s.SetStopMode(RageSoundParams::M_CONTINUE);
{
RageSoundParams p = s[selected].s.GetParams();
p.StopMode = RageSoundParams::M_CONTINUE;
s[selected].s.SetParams( p );
}
break;
/* case SDLK_LEFT: