Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Chart Editor/Gameplay: Fixes countdown and audio artifacts with offsets #3384

Merged
merged 4 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions source/funkin/Conductor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,12 @@ class Conductor
*/
public function update(?songPos:Float, applyOffsets:Bool = true, forceDispatch:Bool = false)
{
var currentTime:Float = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
var currentLength:Float = (FlxG.sound.music != null) ? FlxG.sound.music.length : 0.0;

if (songPos == null)
{
songPos = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
songPos = currentTime;
}

// Take into account instrumental and file format song offsets.
Expand All @@ -409,8 +412,17 @@ class Conductor
var oldBeat:Float = this.currentBeat;
var oldStep:Float = this.currentStep;

// If the song is playing, limit the song position to the length of the song or beginning of the song.
if (FlxG.sound.music != null && FlxG.sound.music.playing)
{
this.songPosition = Math.min(currentLength, Math.max(0, songPos));
}
else
{
this.songPosition = songPos;
}

// Set the song position we are at (for purposes of calculating note positions, etc).
this.songPosition = songPos;

currentTimeChange = timeChanges[0];
if (this.songPosition > 0.0)
Expand All @@ -430,7 +442,8 @@ class Conductor
else if (currentTimeChange != null && this.songPosition > 0.0)
{
// roundDecimal prevents representing 8 as 7.9999999
this.currentStepTime = FlxMath.roundDecimal((currentTimeChange.beatTime * Constants.STEPS_PER_BEAT) + (this.songPosition - currentTimeChange.timeStamp) / stepLengthMs, 6);
this.currentStepTime = FlxMath.roundDecimal((currentTimeChange.beatTime * Constants.STEPS_PER_BEAT)
+ (this.songPosition - currentTimeChange.timeStamp) / stepLengthMs, 6);
this.currentBeatTime = currentStepTime / Constants.STEPS_PER_BEAT;
this.currentMeasureTime = currentStepTime / stepsPerMeasure;
this.currentStep = Math.floor(currentStepTime);
Expand Down
36 changes: 25 additions & 11 deletions source/funkin/play/PlayState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,11 @@ class PlayState extends MusicBeatSubState
}

Conductor.instance.mapTimeChanges(currentChart.timeChanges);
Conductor.instance.update((Conductor.instance.beatLengthMs * -5) + startTimestamp);
var pre:Float = (Conductor.instance.beatLengthMs * -5) + startTimestamp;

trace('Attempting to start at ' + pre);

Conductor.instance.update(pre);

// The song is now loaded. We can continue to initialize the play state.
initCameras();
Expand Down Expand Up @@ -915,7 +919,11 @@ class PlayState extends MusicBeatSubState
{
// Do NOT apply offsets at this point, because they already got applied the previous frame!
Conductor.instance.update(Conductor.instance.songPosition + elapsed * 1000, false);
if (Conductor.instance.songPosition >= (startTimestamp)) startSong();
if (Conductor.instance.songPosition >= (startTimestamp + Conductor.instance.instrumentalOffset))
{
trace("started song at " + Conductor.instance.songPosition);
startSong();
}
}
}
else
Expand Down Expand Up @@ -1391,15 +1399,18 @@ class PlayState extends MusicBeatSubState
// activeNotes.sort(SortUtil.byStrumtime, FlxSort.DESCENDING);
}

if (!startingSong
&& FlxG.sound.music != null
&& (Math.abs(FlxG.sound.music.time - (Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)) > 100
|| Math.abs(vocals.checkSyncError(Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)) > 100))
if (FlxG.sound.music != null)
{
trace("VOCALS NEED RESYNC");
if (vocals != null) trace(vocals.checkSyncError(Conductor.instance.songPosition + Conductor.instance.instrumentalOffset));
trace(FlxG.sound.music.time - (Conductor.instance.songPosition + Conductor.instance.instrumentalOffset));
resyncVocals();
var correctSync:Float = Math.min(FlxG.sound.music.length, Math.max(0, Conductor.instance.songPosition - Conductor.instance.instrumentalOffset));

if (!startingSong && (Math.abs(FlxG.sound.music.time - correctSync) > 5 || Math.abs(vocals.checkSyncError(correctSync)) > 5))
{
trace("VOCALS NEED RESYNC");
if (vocals != null) trace(vocals.checkSyncError(correctSync));
trace(FlxG.sound.music.time);
trace(correctSync);
resyncVocals();
}
}

// Only bop camera if zoom level is below 135%
Expand Down Expand Up @@ -1968,6 +1979,7 @@ class PlayState extends MusicBeatSubState
vocals.play();
vocals.volume = 1.0;
vocals.pitch = playbackRate;
vocals.time = startTimestamp;
resyncVocals();

#if FEATURE_DISCORD_RPC
Expand All @@ -1993,7 +2005,9 @@ class PlayState extends MusicBeatSubState

// Skip this if the music is paused (GameOver, Pause menu, start-of-song offset, etc.)
if (!(FlxG.sound.music?.playing ?? false)) return;
var timeToPlayAt:Float = Conductor.instance.songPosition - Conductor.instance.instrumentalOffset;

var timeToPlayAt:Float = Math.min(FlxG.sound.music.length, Math.max(0, Conductor.instance.songPosition - Conductor.instance.instrumentalOffset));
trace('Resyncing vocals to ${timeToPlayAt}');
FlxG.sound.music.pause();
vocals.pause();

Expand Down