mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 21:47:39 +02:00
Timekeeping Improvements and Small Optimizations (#544)
* make BeatActions coroutines instead of componentrs * pooled scheduled sounds implement S' entity seek * remove debug prints from last two changes * implement absolute time tracking implement DSP time resyncing * optimize GameManager * update TMPro * update IDE packages * fix dsp sync making the drift worse * fix issue with the JSL dll * relocate debug print * make scheduled pitch setter functional * any cpu
This commit is contained in:
@ -22,6 +22,7 @@ namespace HeavenStudio.Util
|
||||
int loopIndex = 0;
|
||||
|
||||
private AudioSource audioSource;
|
||||
private Conductor cond;
|
||||
|
||||
private int pauseTimes = 0;
|
||||
|
||||
@ -34,30 +35,48 @@ namespace HeavenStudio.Util
|
||||
bool playInstant = false;
|
||||
bool played = false;
|
||||
bool queued = false;
|
||||
public bool available = true;
|
||||
|
||||
const double PREBAKE_TIME = 0.5;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
if (!available)
|
||||
{
|
||||
GameManager.instance.SoundObjects.Release(this);
|
||||
return;
|
||||
}
|
||||
|
||||
audioSource = GetComponent<AudioSource>();
|
||||
cond = Conductor.instance;
|
||||
|
||||
available = false;
|
||||
audioSource.clip = clip;
|
||||
audioSource.pitch = pitch;
|
||||
audioSource.volume = volume;
|
||||
audioSource.loop = looping;
|
||||
Conductor cnd = Conductor.instance;
|
||||
|
||||
loopEndBeat = -1;
|
||||
loopIndex = 0;
|
||||
audioSource.Stop();
|
||||
|
||||
if (beat == -1 && !scheduled)
|
||||
{
|
||||
audioSource.Play();
|
||||
playInstant = true;
|
||||
played = true;
|
||||
startTime = AudioSettings.dspTime;
|
||||
audioSource.PlayScheduled(startTime);
|
||||
StartCoroutine(NotRelyOnBeatSound());
|
||||
}
|
||||
else
|
||||
{
|
||||
playInstant = false;
|
||||
scheduledPitch = cnd.SongPitch;
|
||||
startTime = (AudioSettings.dspTime + (cnd.GetSongPosFromBeat(beat) - cnd.songPositionAsDouble)/(double)scheduledPitch) - offset;
|
||||
scheduledPitch = cond.SongPitch;
|
||||
startTime = (AudioSettings.dspTime + (cond.GetSongPosFromBeat(beat) - cond.songPositionAsDouble) / (double)scheduledPitch) - offset;
|
||||
|
||||
if (scheduledPitch != 0 && AudioSettings.dspTime >= startTime)
|
||||
{
|
||||
@ -69,10 +88,15 @@ namespace HeavenStudio.Util
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Conductor cnd = Conductor.instance;
|
||||
cond = Conductor.instance;
|
||||
double dspTime = AudioSettings.dspTime;
|
||||
if (!played)
|
||||
if (!available)
|
||||
{
|
||||
if (!Conductor.instance.isPlaying)
|
||||
{
|
||||
GameManager.instance.SoundObjects.Release(this);
|
||||
return;
|
||||
}
|
||||
if (scheduled)
|
||||
{
|
||||
if (!queued && dspTime > scheduledTime - PREBAKE_TIME)
|
||||
@ -90,7 +114,7 @@ namespace HeavenStudio.Util
|
||||
{
|
||||
if (!queued && dspTime > startTime - PREBAKE_TIME)
|
||||
{
|
||||
startTime = (dspTime + (cnd.GetSongPosFromBeat(beat) - cnd.songPositionAsDouble)/(double)scheduledPitch) - offset;
|
||||
startTime = (dspTime + (cond.GetSongPosFromBeat(beat) - cond.songPositionAsDouble) / (double)scheduledPitch) - offset;
|
||||
audioSource.PlayScheduled(startTime);
|
||||
queued = true;
|
||||
}
|
||||
@ -101,11 +125,11 @@ namespace HeavenStudio.Util
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!played && scheduledPitch != cnd.SongPitch)
|
||||
if (!played && scheduledPitch != cond.SongPitch)
|
||||
{
|
||||
if (cnd.SongPitch == 0)
|
||||
if (cond.SongPitch == 0)
|
||||
{
|
||||
scheduledPitch = cnd.SongPitch;
|
||||
scheduledPitch = cond.SongPitch;
|
||||
if (queued)
|
||||
audioSource.Pause();
|
||||
}
|
||||
@ -115,8 +139,8 @@ namespace HeavenStudio.Util
|
||||
{
|
||||
audioSource.UnPause();
|
||||
}
|
||||
scheduledPitch = cnd.SongPitch;
|
||||
startTime = (dspTime + (cnd.GetSongPosFromBeat(beat) - cnd.songPositionAsDouble)/(double)scheduledPitch);
|
||||
scheduledPitch = cond.SongPitch;
|
||||
startTime = (dspTime + (cond.GetSongPosFromBeat(beat) - cond.songPositionAsDouble) / (double)scheduledPitch);
|
||||
if (queued)
|
||||
audioSource.SetScheduledStartTime(startTime);
|
||||
}
|
||||
@ -129,7 +153,7 @@ namespace HeavenStudio.Util
|
||||
{
|
||||
if (looping && loopEndBeat != -1) // Looping sounds play forever unless params are set.
|
||||
{
|
||||
if (cnd.songPositionInBeats > loopEndBeat)
|
||||
if (cond.songPositionInBeatsAsDouble > loopEndBeat)
|
||||
{
|
||||
KillLoop(fadeTime);
|
||||
loopIndex++;
|
||||
@ -140,10 +164,16 @@ namespace HeavenStudio.Util
|
||||
|
||||
IEnumerator NotRelyOnBeatSound()
|
||||
{
|
||||
if (!looping) // Looping sounds are destroyed manually.
|
||||
if (!Conductor.instance.isPlaying)
|
||||
{
|
||||
yield return new WaitUntil(() => !audioSource.isPlaying);
|
||||
Delete();
|
||||
GameManager.instance.SoundObjects.Release(this);
|
||||
yield break;
|
||||
}
|
||||
WaitUntil yieldIsAudioPlaying = new WaitUntil(() => !audioSource.isPlaying || !Conductor.instance.isPlaying);
|
||||
if (played && !looping) // Looping sounds are destroyed manually.
|
||||
{
|
||||
yield return yieldIsAudioPlaying;
|
||||
GameManager.instance.SoundObjects.Release(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,12 +183,6 @@ namespace HeavenStudio.Util
|
||||
this.fadeTime = fadeTime;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (audioSource != null)
|
||||
audioSource.Stop();
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
if (audioSource != null)
|
||||
@ -171,10 +195,23 @@ namespace HeavenStudio.Util
|
||||
audioSource.UnPause();
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
public void Stop()
|
||||
{
|
||||
GameManager.instance.SoundObjects.Remove(gameObject);
|
||||
Destroy(gameObject);
|
||||
available = true;
|
||||
played = false;
|
||||
queued = false;
|
||||
playInstant = false;
|
||||
looping = false;
|
||||
scheduled = false;
|
||||
beat = 0;
|
||||
loopEndBeat = -1;
|
||||
loopIndex = 0;
|
||||
startTime = 0;
|
||||
|
||||
audioSource.loop = false;
|
||||
audioSource.Stop();
|
||||
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
#region Bend
|
||||
@ -182,12 +219,14 @@ namespace HeavenStudio.Util
|
||||
// minenice: consider doing these in the audio thread so they can work per-sample?
|
||||
public void BendUp(float bendTime, float bendedPitch)
|
||||
{
|
||||
if (!gameObject.activeSelf) return;
|
||||
this.bendedPitch = bendedPitch;
|
||||
StartCoroutine(BendUpLoop(bendTime));
|
||||
}
|
||||
|
||||
public void BendDown(float bendTime)
|
||||
{
|
||||
if (!gameObject.activeSelf) return;
|
||||
StartCoroutine(BendDownLoop(bendTime));
|
||||
}
|
||||
|
||||
@ -225,10 +264,11 @@ namespace HeavenStudio.Util
|
||||
|
||||
public void KillLoop(double fadeTime)
|
||||
{
|
||||
if (!gameObject.activeSelf) return;
|
||||
StartCoroutine(FadeLoop(fadeTime));
|
||||
}
|
||||
|
||||
float loopFadeTimer = 0f;
|
||||
double loopFadeTimer = 0f;
|
||||
IEnumerator FadeLoop(double fadeTime)
|
||||
{
|
||||
float startingVol = audioSource.volume;
|
||||
@ -236,11 +276,11 @@ namespace HeavenStudio.Util
|
||||
while (loopFadeTimer < fadeTime)
|
||||
{
|
||||
loopFadeTimer += Time.deltaTime;
|
||||
audioSource.volume = (float) Math.Max((1f - (loopFadeTimer / fadeTime)) * startingVol, 0.0);
|
||||
audioSource.volume = (float)Math.Max((1f - (loopFadeTimer / fadeTime)) * startingVol, 0.0);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Delete();
|
||||
yield return null;
|
||||
GameManager.instance.SoundObjects.Release(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user