diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx
index bd50b556c..7756313c8 100644
--- a/source/funkin/Conductor.hx
+++ b/source/funkin/Conductor.hx
@@ -290,7 +290,7 @@ class Conductor
 
     if (timeChanges.length > 0)
     {
-      trace('Done mapping time changes: ${timeChanges}' + timeChanges);
+      trace('Done mapping time changes: ${timeChanges}');
     }
 
     // Update currentStepTime
diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx
index 2e98b9c0a..6dc6f55e7 100644
--- a/source/funkin/data/song/SongData.hx
+++ b/source/funkin/data/song/SongData.hx
@@ -86,6 +86,11 @@ class SongMetadata
 
     return result;
   }
+
+  public function toString():String
+  {
+    return 'SongMetadata(${this.songName} by ${this.artist}, variation ${this.variation})';
+  }
 }
 
 enum abstract SongTimeFormat(String) from String to String
@@ -162,6 +167,11 @@ class SongTimeChange
     this.beatTime = beatTime == null ? DEFAULT_BEAT_TIME : beatTime;
     this.beatTuplets = beatTuplets == null ? DEFAULT_BEAT_TUPLETS : beatTuplets;
   }
+
+  public function toString():String
+  {
+    return 'SongTimeChange(${this.timeStamp}ms,${this.bpm}bpm)';
+  }
 }
 
 /**
@@ -232,6 +242,11 @@ class SongMusicData
 
     return result;
   }
+
+  public function toString():String
+  {
+    return 'SongMusicData(${this.songName} by ${this.artist}, variation ${this.variation})';
+  }
 }
 
 typedef SongPlayData =
@@ -271,6 +286,11 @@ class SongPlayableChar
     this.opponent = opponent;
     this.inst = inst;
   }
+
+  public function toString():String
+  {
+    return 'SongPlayableChar(${this.girlfriend}, ${this.opponent}, ${this.inst})';
+  }
 }
 
 class SongChartData
@@ -455,6 +475,11 @@ class SongEventData
   {
     return this.time <= other.time;
   }
+
+  public function toString():String
+  {
+    return 'SongEventData(${this.time}ms, ${this.event}: ${this.value})';
+  }
 }
 
 class SongNoteData
@@ -646,4 +671,10 @@ class SongNoteData
   {
     return this.time <= other.time;
   }
+
+  public function toString():String
+  {
+    return 'SongNoteData(${this.time}ms, ' + (this.length > 0 ? '[${this.length}ms hold]' : '') + ' ${this.data}'
+      + (this.kind != '' ? ' [kind: ${this.kind}])' : ')');
+  }
 }
diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx
index d01f0d42f..cb98ba68e 100644
--- a/source/funkin/ui/debug/charting/ChartEditorState.hx
+++ b/source/funkin/ui/debug/charting/ChartEditorState.hx
@@ -3961,7 +3961,7 @@ class ChartEditorState extends HaxeUIState
       var variation = (metadata.variation == null || metadata.variation == '') ? 'default' : metadata.variation;
 
       // Clone to prevent modifying the original.
-      var metadataClone = Reflect.copy(metadata);
+      var metadataClone:SongMetadata = metadata.clone(variation);
       if (metadataClone != null) songMetadata.set(variation, metadataClone);
 
       songChartData.set(variation, SongRegistry.instance.parseEntryChartData(songId, metadata.variation));
@@ -3969,18 +3969,6 @@ class ChartEditorState extends HaxeUIState
 
     loadSong(songMetadata, songChartData);
 
-    notePreviewDirty = true;
-    notePreviewViewportBoundsDirty = true;
-
-    if (audioInstTrack != null)
-    {
-      audioInstTrack.stop();
-      audioInstTrack = null;
-    }
-
-    Conductor.forceBPM(null); // Disable the forced BPM.
-    Conductor.mapTimeChanges(currentSongMetadata.timeChanges);
-
     sortChartData();
 
     clearVocals();
@@ -4024,6 +4012,8 @@ class ChartEditorState extends HaxeUIState
     Conductor.forceBPM(null); // Disable the forced BPM.
     Conductor.mapTimeChanges(currentSongMetadata.timeChanges);
 
+    notePreviewDirty = true;
+    notePreviewViewportBoundsDirty = true;
     difficultySelectDirty = true;
     opponentPreviewDirty = true;
     playerPreviewDirty = true;