Skip to content

Commit

Permalink
Add more access to AccurateSync & let Soundman do more seeking
Browse files Browse the repository at this point in the history
the soundman stuff is for blocking reasons; hard seeking blocks gameplay when done directly on a sound so we need the music thread to seek instead of the main thread
  • Loading branch information
poco0317 committed Sep 22, 2019
1 parent c7bc664 commit 2453611
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/Etterna/Models/Songs/Song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1958,11 +1958,13 @@ Song::Borp()
PlayParams.fFadeOutLengthSeconds = 1.f;
PlayParams.bAlignBeat = true;
PlayParams.bApplyMusicRate = true;
PlayParams.bAccurateSync = true;

GameSoundManager::PlayMusicParams FallbackMusic;
FallbackMusic.sFile = GetMusicPath();
FallbackMusic.fFadeInLengthSeconds = 1.f;
FallbackMusic.bAlignBeat = true;
FallbackMusic.bAccurateSync = true;

if (PlayParams.fLengthSeconds <
3.f) { // if the songpreview is after the last note
Expand Down
3 changes: 1 addition & 2 deletions src/Etterna/Screen/Gameplay/ScreenGameplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -619,11 +619,10 @@ ScreenGameplay::StartPlayingSong(float fMinTimeToNotes, float fMinTimeToMusic)
ASSERT(fMinTimeToNotes >= 0);
ASSERT(fMinTimeToMusic >= 0);

m_pSoundMusic->SetProperty("AccurateSync", true);

RageSoundParams p;
p.m_fSpeed = GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
p.StopMode = RageSoundParams::M_CONTINUE;
p.m_bAccurateSync = true;

{
const float fFirstSecond = GAMESTATE->m_pCurSong->GetFirstSecond();
Expand Down
7 changes: 7 additions & 0 deletions src/Etterna/Screen/Others/ScreenSelectMusic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,13 @@ ScreenSelectMusic::CheckBackgroundRequests(bool bForce)
PlayParams.bAlignBeat = ALIGN_MUSIC_BEATS;
PlayParams.bApplyMusicRate = true;

// We will leave this FALSE for standard sample music
// Because accurate seeking is slow for MP3.
// The way music playing works does not cause stutter, but
// will cause inconsistent music playing experience and an overall
// negative feel.
PlayParams.bAccurateSync = false;

GameSoundManager::PlayMusicParams FallbackMusic;
FallbackMusic.sFile = m_sLoopMusicPath;
FallbackMusic.fFadeInLengthSeconds =
Expand Down
46 changes: 43 additions & 3 deletions src/Etterna/Singletons/GameSoundManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,20 @@ struct MusicToPlay
bool bForceLoop;
float fStartSecond, fLengthSeconds, fFadeInLengthSeconds,
fFadeOutLengthSeconds;
bool bAlignBeat, bApplyMusicRate;
bool bAlignBeat, bApplyMusicRate, bAccurateSync;
MusicToPlay() { HasTiming = false; }
};
vector<MusicToPlay> g_MusicsToPlay;
static GameSoundManager::PlayMusicParams g_FallbackMusicParams;

// A position to be set on a sound
struct SoundPositionSetter
{
RageSound* m_psound;
float fSeconds;
};
vector<SoundPositionSetter> g_PositionsToSet;

void
GameSoundManager::StartMusic(MusicToPlay& ToPlay)
{
Expand Down Expand Up @@ -266,6 +274,7 @@ GameSoundManager::StartMusic(MusicToPlay& ToPlay)
p.m_fFadeInSeconds = ToPlay.fFadeInLengthSeconds;
p.m_fFadeOutSeconds = ToPlay.fFadeOutLengthSeconds;
p.m_StartTime = when;
p.m_bAccurateSync = ToPlay.bAccurateSync;
if (ToPlay.bForceLoop)
p.StopMode = RageSoundParams::M_LOOP;
NewMusic->m_Music->SetParams(p);
Expand Down Expand Up @@ -317,7 +326,8 @@ bool
GameSoundManager::SoundWaiting()
{
return !g_SoundsToPlayOnce.empty() || !g_SoundsToPlayOnceFromDir.empty() ||
!g_SoundsToPlayOnceFromAnnouncer.empty() || !g_MusicsToPlay.empty();
!g_SoundsToPlayOnceFromAnnouncer.empty() ||
!g_MusicsToPlay.empty() || !g_PositionsToSet.empty();
}

void
Expand Down Expand Up @@ -378,6 +388,20 @@ GameSoundManager::StartQueuedSounds()
}
}

void
GameSoundManager::HandleSetPosition()
{
g_Mutex->Lock();
vector<SoundPositionSetter> vec = g_PositionsToSet;
g_PositionsToSet.clear();
g_Mutex->Unlock();
if (!vec.empty()) {
for (unsigned i = 0; i < vec.size(); i++) {
vec[i].m_psound->SetPositionSeconds(vec[i].fSeconds);
}
}
}

void
GameSoundManager::Flush()
{
Expand Down Expand Up @@ -410,6 +434,8 @@ MusicThread_start(void* p)

soundman->StartQueuedSounds();

soundman->HandleSetPosition();

if (bFlushing) {
g_Mutex->Lock();
g_Mutex->Signal();
Expand Down Expand Up @@ -689,6 +715,18 @@ GameSoundManager::GetPlayingMusicTiming()
return g_Playing->m_Timing;
}

void
GameSoundManager::SetSoundPosition(RageSound* s, float fSeconds)
{
SoundPositionSetter snd;
snd.fSeconds = fSeconds;
snd.m_psound = s;
g_Mutex->Lock();
g_PositionsToSet.push_back(snd);
g_Mutex->Broadcast();
g_Mutex->Unlock();
}

void
GameSoundManager::PlayMusic(const RString& sFile,
const TimingData* pTiming,
Expand All @@ -698,7 +736,8 @@ GameSoundManager::PlayMusic(const RString& sFile,
float fFadeInLengthSeconds,
float fFadeOutLengthSeconds,
bool bAlignBeat,
bool bApplyMusicRate)
bool bApplyMusicRate,
bool bAccurateSync)
{
PlayMusicParams params;
params.sFile = sFile;
Expand Down Expand Up @@ -742,6 +781,7 @@ GameSoundManager::PlayMusic(PlayMusicParams params,
ToPlay.fFadeOutLengthSeconds = params.fFadeOutLengthSeconds;
ToPlay.bAlignBeat = params.bAlignBeat;
ToPlay.bApplyMusicRate = params.bApplyMusicRate;
ToPlay.bAccurateSync = params.bAccurateSync;

/* Add the MusicToPlay to the g_MusicsToPlay queue. */
g_Mutex->Lock();
Expand Down
10 changes: 9 additions & 1 deletion src/Etterna/Singletons/GameSoundManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class GameSoundManager : MessageSubscriber
fFadeOutLengthSeconds = 0;
bAlignBeat = true;
bApplyMusicRate = false;
bAccurateSync = false;
}

RString sFile;
Expand All @@ -44,6 +45,7 @@ class GameSoundManager : MessageSubscriber
float fFadeOutLengthSeconds;
bool bAlignBeat;
bool bApplyMusicRate;
bool bAccurateSync;
};
void PlayMusic(PlayMusicParams params,
PlayMusicParams FallbackMusicParams = PlayMusicParams());
Expand All @@ -55,7 +57,8 @@ class GameSoundManager : MessageSubscriber
float fFadeInLengthSeconds = 0,
float fade_len = 0,
bool align_beat = true,
bool bApplyMusicRate = false);
bool bApplyMusicRate = false,
bool bAccurateSync = false);
void StopMusic() { PlayMusic(""); }
void DimMusic(float fVolume, float fDurationSeconds);
RString GetMusicPath() const;
Expand All @@ -72,11 +75,16 @@ class GameSoundManager : MessageSubscriber
void WithRageSoundPlaying(function<void(RageSound*)> f);
TimingData GetPlayingMusicTiming();

// Set a sound's position given its pointer
// Meant to avoid blocking the game execution (stutter)
void SetSoundPosition(RageSound* s, float fSeconds);

void StartMusic(MusicToPlay& ToPlay);
void DoPlayOnce(RString sPath);
void StartQueuedSounds();
void DoPlayOnceFromDir(RString sPath);
bool SoundWaiting();
void HandleSetPosition();

std::shared_ptr<LuaReference> soundPlayCallback;
unsigned int recentPCMSamplesBufferSize = 1024;
Expand Down
1 change: 1 addition & 0 deletions src/RageUtil/Sound/RageSound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@ RageSound::ApplyParams()
m_pSource->SetProperty("LengthSeconds", m_Param.m_LengthSeconds);
m_pSource->SetProperty("FadeInSeconds", m_Param.m_fFadeInSeconds);
m_pSource->SetProperty("FadeSeconds", m_Param.m_fFadeOutSeconds);
m_pSource->SetProperty("AccurateSync", m_Param.m_bAccurateSync);

float fVolume = m_Param.m_Volume * SOUNDMAN->GetMixVolume();
if (!m_Param.m_bIsCriticalSound)
Expand Down
5 changes: 4 additions & 1 deletion src/RageUtil/Sound/RageSound.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* RageSound - High-level sound object. */
/* RageSound - High-level sound object. */

#ifndef RAGE_SOUND_H
#define RAGE_SOUND_H
Expand Down Expand Up @@ -55,6 +55,9 @@ struct RageSoundParams
float m_fPitch{ 1.0f };
float m_fSpeed{ 1.0f };

// Accurate Sync (for now only useful for MP3s)
bool m_bAccurateSync{ false };

/* Optional driver feature: time to actually start playing sounds.
* If zero, or if not supported, the sound will start immediately. */
RageTimer m_StartTime;
Expand Down

0 comments on commit 2453611

Please sign in to comment.