@@ -1170,28 +1170,9 @@ class PlayState extends MusicBeatSubState
11701170 Conductor .instance .formatOffset = 0.0 ;
11711171 }
11721172
1173- // Lime has some precision loss when getting the sound current position
1174- // Since the notes scrolling is dependant on the sound time that caused it to appear "stuttery" for some people
1175- // As a workaround for that, we lerp the conductor position to the music time to fill the gap in this lost precision making the scrolling smoother
1176- // The previous method where it "guessed" the song position based on the elapsed time had some flaws
1177- // Somtimes the songPosition would exceed the music length causing issues in other places
1178- // And it was frame dependant which we don't like!!
11791173 if (FlxG .sound .music .playing )
11801174 {
1181- final audioDiff : Float = Math .round (Math .abs (FlxG .sound .music .time - (Conductor .instance .songPosition - Conductor .instance .combinedOffset )));
1182- if (audioDiff <= CONDUCTOR_DRIFT_THRESHOLD )
1183- {
1184- // Only do neat & smooth lerps as long as the lerp doesn't fuck up and go WAY behind the music time triggering false resyncs
1185- final easeRatio : Float = 1.0 - Math .exp (- (MUSIC_EASE_RATIO * playbackRate ) * elapsed );
1186- Conductor .instance .update (FlxMath .lerp (Conductor .instance .songPosition , FlxG .sound .music .time + Conductor .instance .combinedOffset , easeRatio ), false );
1187- }
1188- else
1189- {
1190- // Fallback to properly update the conductor incase the lerp messed up
1191- // Shouldn't be fallen back to unless you're lagging alot
1192- trace (' WARNING ' .bg_yellow ().bold () + ' Normal Conductor Update!! are you lagging?' );
1193- Conductor .instance .update ();
1194- }
1175+ Conductor .instance .update ();
11951176 }
11961177 }
11971178
@@ -1551,31 +1532,19 @@ class PlayState extends MusicBeatSubState
15511532 FlxG .sound .music .pause ();
15521533 musicPausedBySubState = true ;
15531534 }
1535+ vocals ?. pause ();
15541536
15551537 // Pause any sounds that are playing and keep track of them.
15561538 // Vocals are also paused here but are not included as they are handled separately.
15571539 if (Std .isOfType (subState , PauseSubState ))
15581540 {
15591541 FlxG .sound .list .forEachAlive (function (sound : FlxSound ) {
1560- if (! sound .active || sound == FlxG .sound .music ) return ;
1561- // In case it's a scheduled sound
1562- if (Std .isOfType (sound , FunkinSound ))
1563- {
1564- var funkinSound : FunkinSound = cast sound ;
1565- if (funkinSound != null && ! funkinSound .isPlaying ) return ;
1566- }
1567- if (! sound .playing && sound .time >= 0 ) return ;
1568- sound .pause ();
1542+ if (! sound .playing || ! sound .active || sound == FlxG .sound .music ) return ;
15691543 soundsPausedBySubState .add (sound );
15701544 });
1545+ vocals ?. forEach (function (voice : FunkinSound ) soundsPausedBySubState .remove (voice ));
15711546
1572- vocals ?. forEach (function (voice : FunkinSound ) {
1573- soundsPausedBySubState .remove (voice );
1574- });
1575- }
1576- else
1577- {
1578- vocals ?. pause ();
1547+ for (sound in soundsPausedBySubState ) sound .pause ();
15791548 }
15801549 }
15811550
@@ -1629,42 +1598,9 @@ class PlayState extends MusicBeatSubState
16291598
16301599 if (event .eventCanceled ) return ;
16311600
1632- // Pause any sounds that are playing and keep track of them.
1633- // Vocals are also paused here but are not included as they are handled separately.
1634- if (! isGameOverState )
1635- {
1636- FlxG .sound .list .forEachAlive (function (sound : FlxSound ) {
1637- if (! sound .active || sound == FlxG .sound .music ) return ;
1638- // In case it's a scheduled sound
1639- if (Std .isOfType (sound , FunkinSound ))
1640- {
1641- var funkinSound : FunkinSound = cast sound ;
1642- if (funkinSound != null && ! funkinSound .isPlaying ) return ;
1643- }
1644- if (! sound .playing && sound .time >= 0 ) return ;
1645- sound .pause ();
1646- soundsPausedBySubState .add (sound );
1647- });
1648-
1649- vocals ?. forEach (function (voice : FunkinSound ) {
1650- soundsPausedBySubState .remove (voice );
1651- });
1652- }
1653- else
1654- {
1655- vocals ?. pause ();
1656- }
1657-
16581601 // Resume vwooshTimer
16591602 if (! vwooshTimer .finished ) vwooshTimer .active = true ;
16601603
1661- // Resume music if we paused it.
1662- if (musicPausedBySubState )
1663- {
1664- if (FlxG .sound .music != null ) FlxG .sound .music .play ();
1665- musicPausedBySubState = false ;
1666- }
1667-
16681604 // The logic here is that if this sound doesn't auto-destroy
16691605 // then it's gonna be reused somewhere, so we just stop it instead.
16701606 forEachPausedSound (s -> needsReset ? (s .autoDestroy ? s .destroy () : s .stop ()) : s .resume ());
@@ -1687,8 +1623,10 @@ class PlayState extends MusicBeatSubState
16871623 currentConversation .resumeMusic ();
16881624 }
16891625
1690- // Re-sync vocals.
1691- if (FlxG .sound .music != null && ! startingSong && ! isInCutscene ) resyncVocals ();
1626+ // If we have started the song, resync it instead that plays the song, else resume music if we paused it.
1627+ if (FlxG .sound .music != null && ! startingSong && ! isInCutscene ) resyncVocals (true );
1628+ else if (musicPausedBySubState ) FlxG .sound .music ?. play ();
1629+ musicPausedBySubState = false ;
16921630
16931631 // Resume the countdown.
16941632 Countdown .resumeCountdown ();
@@ -1890,19 +1828,19 @@ class PlayState extends MusicBeatSubState
18901828 @:privateAccess // todo: maybe make the groups public :thinking:
18911829 {
18921830 vocals .playerVoices ?. forEachAlive (function (voice : FunkinSound ) {
1893- var currentRawVoiceTime : Float = voice .time + vocals .playerVoicesOffset ;
1894- if (Math .abs (currentRawVoiceTime - correctSync ) > Math .abs (playerVoicesError )) playerVoicesError = currentRawVoiceTime - correctSync ;
1831+ var currentRawVoiceTime : Float = voice .getActualTime () + vocals .playerVoicesOffset ;
1832+ if (Math .abs (currentRawVoiceTime - correctSync ) > Math .abs (playerVoicesError ) && voice . playing ) playerVoicesError = currentRawVoiceTime - correctSync ;
18951833 });
18961834
18971835 vocals .opponentVoices ?. forEachAlive (function (voice : FunkinSound ) {
1898- var currentRawVoiceTime : Float = voice .time + vocals .opponentVoicesOffset ;
1899- if (Math .abs (currentRawVoiceTime - correctSync ) > Math .abs (opponentVoicesError )) opponentVoicesError = currentRawVoiceTime - correctSync ;
1836+ var currentRawVoiceTime : Float = voice .getActualTime () + vocals .opponentVoicesOffset ;
1837+ if (Math .abs (currentRawVoiceTime - correctSync ) > Math .abs (opponentVoicesError ) && voice . playing ) opponentVoicesError = currentRawVoiceTime - correctSync ;
19001838 });
19011839 }
19021840 }
19031841
19041842 if (! startingSong
1905- && (Math .abs (FlxG .sound .music .time - correctSync ) > RESYNC_THRESHOLD
1843+ && (Math .abs (FlxG .sound .music .getActualTime () - correctSync ) > RESYNC_THRESHOLD
19061844 || Math .abs (playerVoicesError ) > RESYNC_THRESHOLD
19071845 || Math .abs (opponentVoicesError ) > RESYNC_THRESHOLD ))
19081846 {
@@ -1912,7 +1850,7 @@ class PlayState extends MusicBeatSubState
19121850 trace (playerVoicesError );
19131851 trace (opponentVoicesError );
19141852 }
1915- trace (FlxG .sound .music .time );
1853+ trace (FlxG .sound .music .getActualTime () );
19161854 trace (correctSync );
19171855 resyncVocals ();
19181856 }
@@ -2588,7 +2526,7 @@ class PlayState extends MusicBeatSubState
25882526
25892527 if (! overrideMusic && ! isGamePaused && currentChart != null )
25902528 {
2591- currentChart ?. playInst (1.0 , currentInstrumental , false );
2529+ currentChart ?. buildInst (1.0 , currentInstrumental , false );
25922530 }
25932531
25942532 if (FlxG .sound .music == null )
@@ -2601,8 +2539,6 @@ class PlayState extends MusicBeatSubState
26012539 if (mayPauseGame ) endSong (skipEndingTransition );
26022540 };
26032541
2604- FlxG .sound .music .pause ();
2605- FlxG .sound .music .time = startTimestamp ;
26062542 FlxG .sound .music .pitch = playbackRate ;
26072543
26082544 if (Preferences .subtitles )
@@ -2624,7 +2560,6 @@ class PlayState extends MusicBeatSubState
26242560 trace (' Playing vocals...' );
26252561 add (vocals );
26262562
2627- vocals .time = startTimestamp - Conductor .instance .instrumentalOffset ;
26282563 vocals .pitch = playbackRate ;
26292564 vocals .playerVolume = playerVocalsVolume ;
26302565 vocals .opponentVolume = opponentVocalsVolume ;
@@ -2633,10 +2568,10 @@ class PlayState extends MusicBeatSubState
26332568 // trace('${FlxG.sound.music.time}');
26342569 // trace('${vocals.time}');
26352570
2636- vocals .play ();
2571+ vocals .play (true , startTimestamp - Conductor . instance . instrumentalOffset );
26372572 }
26382573
2639- FlxG .sound .music .play ();
2574+ FlxG .sound .music .play (true , startTimestamp );
26402575
26412576 #if FEATURE_DISCORD_RPC
26422577 // Updating Discord Rich Presence (with Time Left)
@@ -2662,32 +2597,22 @@ class PlayState extends MusicBeatSubState
26622597 #if FEATURE_NEWGROUNDS
26632598 Events .logStartSong (currentSong .id , currentVariation );
26642599 #end
2665-
2666- resyncVocals ();
26672600 }
26682601
26692602 /**
26702603 * Resynchronize the vocal tracks if they have become offset from the instrumental.
26712604 */
2672- function resyncVocals (): Void
2605+ function resyncVocals (force = false ): Void
26732606 {
2674- if (vocals == null ) return ;
2675-
2676- // Skip this if the music is paused (GameOver, Pause menu, start-of-song offset, etc.)
2677- if (! (FlxG .sound .music ?. playing ?? false )) return ;
2678-
2679- var timeToPlayAt : Float = Math .min (FlxG .sound .music .length ,
2680- Math .max (Math .min (Conductor .instance .combinedOffset , 0 ), Conductor .instance .songPosition ) - Conductor .instance .combinedOffset );
2681- trace (' Resyncing vocals to ${timeToPlayAt }' );
2682-
2683- FlxG .sound .music .pause ();
2684- vocals .pause ();
2685-
2686- FlxG .sound .music .time = timeToPlayAt ;
2687- FlxG .sound .music .play (false , timeToPlayAt );
2607+ if (FlxG .sound .music != null && force || (vocals != null && FlxG .sound .music .playing ))
2608+ {
2609+ var timeToPlayAt : Float = Math .min (FlxG .sound .music .length ,
2610+ Math .max (Math .min (Conductor .instance .combinedOffset , 0 ), Conductor .instance .songPosition ) - Conductor .instance .combinedOffset );
2611+ trace (' Resyncing vocals to ${timeToPlayAt }' );
26882612
2689- vocals .time = timeToPlayAt ;
2690- vocals .play (false , timeToPlayAt );
2613+ FlxG .sound .music .play (true , timeToPlayAt );
2614+ vocals ?. play (true , timeToPlayAt );
2615+ }
26912616 }
26922617
26932618 /**
@@ -3407,8 +3332,9 @@ class PlayState extends MusicBeatSubState
34073332 */
34083333 public function endSong (rightGoddamnNow : Bool = false ): Void
34093334 {
3410- if (FlxG .sound .music != null ) FlxG .sound .music .volume = 0 ;
3411- if (vocals != null ) vocals .volume = 0 ;
3335+ FlxG .sound .music ?. stop ();
3336+ vocals ?. stop ();
3337+
34123338 mayPauseGame = false ;
34133339 isSongEnd = true ;
34143340
@@ -3843,7 +3769,6 @@ class PlayState extends MusicBeatSubState
38433769 }
38443770
38453771 persistentUpdate = false ;
3846- vocals ?. stop ();
38473772 camHUD .alpha = 1 ;
38483773
38493774 var talliesToUse : Tallies = PlayStatePlaylist .isStoryMode ? Highscore .talliesLevel : Highscore .tallies ;
@@ -4087,7 +4012,7 @@ class PlayState extends MusicBeatSubState
40874012
40884013 handleSkippedNotes ();
40894014 SongEventRegistry .handleSkippedEvents (songEvents , Conductor .instance .songPosition );
4090- if (FlxG .sound .music != null && FlxG .sound .music .playing && preventDeath ) regenNoteData (FlxG .sound .music .time );
4015+ if (FlxG .sound .music != null && FlxG .sound .music .playing && preventDeath ) regenNoteData (FlxG .sound .music .getActualTime () );
40914016
40924017 Conductor .instance .update (FlxG .sound ?. music ?. time ?? 0.0 );
40934018
0 commit comments