mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 21:47:39 +02:00
workaround sneaky spirits pause jank
make BeatAction also wait for conductor DSP to start remove leftover logic from old conductor sync fix #630 fix #632 fix #633
This commit is contained in:
@ -46,7 +46,7 @@ namespace HeavenStudio
|
||||
// Current time of the song
|
||||
private double time;
|
||||
double dspTime;
|
||||
double absTime, absTimeAdjust;
|
||||
double absTime, absTimeAdjust, lastAbsTime;
|
||||
double dspSizeSeconds;
|
||||
double dspMargin = 128 / 44100.0;
|
||||
bool deferTimeKeeping = false;
|
||||
@ -56,7 +56,7 @@ namespace HeavenStudio
|
||||
private double dspStart;
|
||||
private float dspStartTime => (float)dspStart;
|
||||
public double dspStartTimeAsDouble => dspStart;
|
||||
DateTime startTime;
|
||||
DateTime startTime, lastMixTime;
|
||||
|
||||
//the beat we started at
|
||||
private double startPos;
|
||||
@ -98,38 +98,33 @@ namespace HeavenStudio
|
||||
public void SetTimelinePitch(float pitch)
|
||||
{
|
||||
if (isPaused) return;
|
||||
if (pitch != 0 && pitch * minigamePitch != SongPitch)
|
||||
if (pitch != 0 && pitch != timelinePitch)
|
||||
{
|
||||
Debug.Log("added pitch change " + pitch * minigamePitch + " at" + absTime);
|
||||
addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * minigamePitch });
|
||||
}
|
||||
|
||||
timelinePitch = pitch;
|
||||
musicSource.pitch = SongPitch;
|
||||
|
||||
if (musicSource != null && musicSource.clip != null)
|
||||
{
|
||||
musicSource.pitch = SongPitch;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMinigamePitch(float pitch)
|
||||
{
|
||||
if (pitch != 0 && pitch * timelinePitch != SongPitch)
|
||||
if (isPaused || !isPlaying) return;
|
||||
if (pitch != 0 && pitch != minigamePitch)
|
||||
{
|
||||
Debug.Log("added pitch change " + pitch * timelinePitch + " at" + absTime);
|
||||
addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * timelinePitch });
|
||||
}
|
||||
|
||||
minigamePitch = pitch;
|
||||
musicSource.pitch = SongPitch;
|
||||
}
|
||||
|
||||
public void SetMinigamePitch(float pitch, double beat)
|
||||
{
|
||||
BeatAction.New(this,
|
||||
new List<BeatAction.Action> {
|
||||
new BeatAction.Action(beat, delegate {
|
||||
SetMinigamePitch(pitch);
|
||||
}),
|
||||
}
|
||||
);
|
||||
if (musicSource != null && musicSource.clip != null)
|
||||
{
|
||||
musicSource.pitch = SongPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void Awake()
|
||||
@ -173,6 +168,9 @@ namespace HeavenStudio
|
||||
public void Play(double beat)
|
||||
{
|
||||
if (isPlaying) return;
|
||||
addedPitchChanges.Clear();
|
||||
addedPitchChanges.Add(new AddedPitchChange { time = 0, pitch = timelinePitch });
|
||||
minigamePitch = 1f;
|
||||
|
||||
if (isPaused)
|
||||
{
|
||||
@ -184,8 +182,6 @@ namespace HeavenStudio
|
||||
dspSizeSeconds = config.dspBufferSize / (double)config.sampleRate;
|
||||
Debug.Log($"dsp size: {dspSizeSeconds}");
|
||||
dspMargin = 2 * dspSizeSeconds;
|
||||
addedPitchChanges.Clear();
|
||||
addedPitchChanges.Add(new AddedPitchChange { time = 0, pitch = SongPitch });
|
||||
|
||||
SetMinigameVolume(1f);
|
||||
}
|
||||
@ -204,7 +200,7 @@ namespace HeavenStudio
|
||||
double musicStartDelay = -offset - startPos;
|
||||
if (musicStartDelay > 0)
|
||||
{
|
||||
musicScheduledTime = dspTime + (musicStartDelay / SongPitch) + 2*dspSizeSeconds;
|
||||
musicScheduledTime = dspTime + (musicStartDelay / timelinePitch) + 2*dspSizeSeconds;
|
||||
dspStart = dspTime + 2*dspSizeSeconds;
|
||||
}
|
||||
else
|
||||
@ -212,8 +208,9 @@ namespace HeavenStudio
|
||||
musicScheduledTime = dspTime + 2*dspSizeSeconds;
|
||||
dspStart = dspTime + 2*dspSizeSeconds;
|
||||
}
|
||||
musicScheduledPitch = SongPitch;
|
||||
musicSource.PlayScheduled(musicScheduledTime);
|
||||
musicScheduledPitch = timelinePitch;
|
||||
musicSource.pitch = timelinePitch;
|
||||
Debug.Log($"playback scheduled for dsptime {dspStart}");
|
||||
}
|
||||
if (musicSource.clip == null)
|
||||
@ -227,6 +224,7 @@ namespace HeavenStudio
|
||||
|
||||
startTime = DateTime.Now;
|
||||
absTimeAdjust = 0;
|
||||
lastAbsTime = 0;
|
||||
deferTimeKeeping = musicSource.clip != null;
|
||||
|
||||
isPlaying = true;
|
||||
@ -235,11 +233,11 @@ namespace HeavenStudio
|
||||
|
||||
void OnAudioFilterRead(float[] data, int channels)
|
||||
{
|
||||
if (!deferTimeKeeping) return;
|
||||
// don't actually do anything with the data
|
||||
|
||||
// wait until we get a dsp update before starting to keep time
|
||||
double dsp = AudioSettings.dspTime;
|
||||
if (dsp >= dspStart - dspSizeSeconds)
|
||||
if (deferTimeKeeping && dsp >= dspStart - dspSizeSeconds)
|
||||
{
|
||||
deferTimeKeeping = false;
|
||||
Debug.Log($"dsptime: {dsp}, deferred timekeeping for {DateTime.Now - startTime} seconds (delta dsp {dsp - dspStart})");
|
||||
@ -247,6 +245,7 @@ namespace HeavenStudio
|
||||
absTimeAdjust = 0;
|
||||
dspStart = dsp;
|
||||
}
|
||||
lastMixTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
@ -255,6 +254,7 @@ namespace HeavenStudio
|
||||
isPlaying = false;
|
||||
isPaused = true;
|
||||
deferTimeKeeping = false;
|
||||
SetMinigamePitch(1f);
|
||||
|
||||
musicSource.Stop();
|
||||
Util.SoundByte.PauseOneShots();
|
||||
@ -276,6 +276,7 @@ namespace HeavenStudio
|
||||
isPlaying = false;
|
||||
isPaused = false;
|
||||
deferTimeKeeping = false;
|
||||
SetMinigamePitch(1f);
|
||||
|
||||
musicSource.Stop();
|
||||
}
|
||||
@ -377,48 +378,29 @@ namespace HeavenStudio
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (isPlaying)
|
||||
double dsp = AudioSettings.dspTime;
|
||||
if (isPlaying && !(isPaused || deferTimeKeeping))
|
||||
{
|
||||
double dsp = AudioSettings.dspTime;
|
||||
if (dsp < musicScheduledTime && musicScheduledPitch != SongPitch)
|
||||
{
|
||||
if (SongPitch == 0f)
|
||||
{
|
||||
musicSource.Pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (musicScheduledPitch == 0f)
|
||||
musicSource.UnPause();
|
||||
musicScheduledPitch = SongPitch;
|
||||
//dspTime to sync with audio thread in case of drift
|
||||
dspTime = dsp - dspStart;
|
||||
|
||||
musicScheduledTime = (dsp + (-GameManager.instance.Beatmap.data.offset - songPositionAsDouble) / (double)SongPitch);
|
||||
musicSource.SetScheduledStartTime(musicScheduledTime);
|
||||
absTime = (DateTime.Now - startTime).TotalSeconds;
|
||||
|
||||
if (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
|
||||
{
|
||||
int i = 0;
|
||||
while (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
|
||||
{
|
||||
i++;
|
||||
absTimeAdjust = (dspTime - absTime + absTimeAdjust) * 0.5;
|
||||
if (i > 8) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!deferTimeKeeping)
|
||||
{
|
||||
absTime = (DateTime.Now - startTime).TotalSeconds;
|
||||
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
|
||||
|
||||
//dspTime to sync with audio thread in case of drift
|
||||
dspTime = dsp - dspStart;
|
||||
if (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
|
||||
{
|
||||
int i = 0;
|
||||
while (Math.Abs(absTime + absTimeAdjust - dspTime) > dspMargin)
|
||||
{
|
||||
i++;
|
||||
absTimeAdjust = (dspTime - absTime + absTimeAdjust) * 0.5;
|
||||
if (i > 8) break;
|
||||
}
|
||||
}
|
||||
|
||||
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
|
||||
|
||||
songPos = startPos + time;
|
||||
songPosBeat = GetBeatFromSongPos(songPos);
|
||||
}
|
||||
songPos = startPos + time;
|
||||
songPosBeat = GetBeatFromSongPos(songPos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -655,7 +637,7 @@ namespace HeavenStudio
|
||||
|
||||
public bool NotStopped()
|
||||
{
|
||||
return Conductor.instance.isPlaying == true || Conductor.instance.isPaused == true;
|
||||
return Conductor.instance.isPlaying || Conductor.instance.isPaused;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user