Skip to content

Commit 67c2b49

Browse files
committed
Improved song resample performance
1 parent 5f0570e commit 67c2b49

File tree

3 files changed

+32
-15
lines changed

3 files changed

+32
-15
lines changed

src/main/java/net/raphimc/noteblocklib/model/Song.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,15 @@ public String getHumanReadableLength() {
5454
public int tickToMilliseconds(final int tick) {
5555
final Set<Integer> tempoEventTicks = new TreeSet<>(this.tempoEvents.getTicks());
5656
tempoEventTicks.add(tick);
57-
tempoEventTicks.removeIf(t -> t > tick);
5857

5958
int lastTick = 0;
6059
float totalMilliseconds = 0;
6160
for (int tempoTick : tempoEventTicks) {
62-
final float tps = this.tempoEvents.get(lastTick);
61+
if (tempoTick > tick) {
62+
break;
63+
}
64+
65+
final float tps = this.tempoEvents.getEffectiveTempo(lastTick);
6366
final int ticksInSegment = tempoTick - lastTick;
6467
final float segmentMilliseconds = (ticksInSegment / tps) * 1000F;
6568
totalMilliseconds += segmentMilliseconds;
@@ -76,13 +79,13 @@ public int millisecondsToTick(final int milliseconds) {
7679
int lastTick = 0;
7780
float totalMilliseconds = 0;
7881
for (int tempoTick : tempoEventTicks) {
79-
final float tps = this.tempoEvents.get(lastTick);
82+
final float tps = this.tempoEvents.getEffectiveTempo(lastTick);
8083
final int ticksInSegment = tempoTick - lastTick;
8184
final float segmentMilliseconds = (ticksInSegment / tps) * 1000F;
8285

8386
if (totalMilliseconds + segmentMilliseconds >= milliseconds) {
84-
float remainingMilliseconds = milliseconds - totalMilliseconds;
85-
int ticksToAdd = Math.round((remainingMilliseconds / 1000F) * tps);
87+
final float remainingMilliseconds = milliseconds - totalMilliseconds;
88+
final int ticksToAdd = Math.round((remainingMilliseconds / 1000F) * tps);
8689
return lastTick + ticksToAdd;
8790
}
8891

src/main/java/net/raphimc/noteblocklib/model/TempoEvents.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ public float get(final int tick) {
3636
}
3737

3838
public float getEffectiveTempo(final int tick) {
39-
return this.tempoEvents.floorEntry(tick).getValue();
39+
final Float tempo = this.tempoEvents.get(tick);
40+
if (tempo != null) {
41+
return tempo;
42+
} else {
43+
return this.tempoEvents.floorEntry(tick).getValue();
44+
}
4045
}
4146

4247
public void set(final int tick, final float tempo) {

src/main/java/net/raphimc/noteblocklib/util/SongResampler.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@
2020
import net.raphimc.noteblocklib.model.Note;
2121
import net.raphimc.noteblocklib.model.Song;
2222

23-
import java.util.ArrayList;
24-
import java.util.HashMap;
25-
import java.util.List;
26-
import java.util.Map;
23+
import java.util.*;
2724

2825
public class SongResampler {
2926

@@ -62,12 +59,24 @@ public static void precomputeTempoEvents(final Song song) {
6259
}
6360

6461
final float newTempo = song.getTempoEvents().getTempoRange()[1]; // Highest tempo in song
65-
6662
final Map<Integer, List<Note>> newNotes = new HashMap<>();
67-
for (int tick : song.getNotes().getTicks()) {
68-
final int millis = song.tickToMilliseconds(tick);
69-
final int newTick = Math.round(newTempo * millis / 1000);
70-
newNotes.computeIfAbsent(newTick, k -> new ArrayList<>()).addAll(song.getNotes().get(tick));
63+
final Set<Integer> ticks = new TreeSet<>(song.getNotes().getTicks());
64+
ticks.addAll(song.getTempoEvents().getTicks());
65+
66+
int lastTick = 0;
67+
float totalMilliseconds = 0;
68+
for (int tick : ticks) {
69+
final float tps = song.getTempoEvents().getEffectiveTempo(lastTick);
70+
final int ticksInSegment = tick - lastTick;
71+
final float segmentMilliseconds = (ticksInSegment / tps) * 1000F;
72+
totalMilliseconds += segmentMilliseconds;
73+
lastTick = tick;
74+
75+
final List<Note> notes = song.getNotes().get(tick);
76+
if (notes != null) {
77+
final int newTick = Math.round(newTempo * totalMilliseconds / 1000F);
78+
newNotes.computeIfAbsent(newTick, k -> new ArrayList<>()).addAll(notes);
79+
}
7180
}
7281

7382
song.getNotes().clear();

0 commit comments

Comments
 (0)