DivSongTimestamps, part 3

This commit is contained in:
tildearrow 2025-10-29 02:39:52 -05:00
parent 2f11128c8d
commit ecfea6033a
6 changed files with 48 additions and 10 deletions

View file

@ -621,6 +621,15 @@ void DivSubSong::calcTimestamps(int chans, std::vector<DivGroovePattern>& groove
break;
}
// log row time here
if (!endOfSong) {
if (rowChanged) {
if (ts.orders[prevOrder]==NULL) ts.orders[prevOrder]=new DivSongTimestamps::Timestamp[DIV_MAX_ROWS];
ts.orders[prevOrder][prevRow]=DivSongTimestamps::Timestamp(ts.totalSeconds,ts.totalMicros);
rowChanged=false;
}
}
// update playback time
double dt=divider*((double)virtualTempoN/(double)MAX(1,virtualTempoD));
ts.totalTicks++;
@ -636,15 +645,6 @@ void DivSubSong::calcTimestamps(int chans, std::vector<DivGroovePattern>& groove
// who's gonna play a song for 68 years?
if (ts.totalSeconds<0x7fffffff) ts.totalSeconds++;
}
// log row time here
if (!endOfSong) {
if (rowChanged) {
if (ts.orders[curOrder]==NULL) ts.orders[curOrder]=new DivSongTimestamps::Timestamp[DIV_MAX_ROWS];
ts.orders[curOrder][curRow]=DivSongTimestamps::Timestamp(ts.totalSeconds,ts.totalMicros);
rowChanged=false;
}
}
if (ts.maxRow[curOrder]<curRow) ts.maxRow[curOrder]=curRow;
}

View file

@ -172,6 +172,7 @@ struct DivSongTimestamps {
int totalSeconds;
int totalMicros;
int totalTicks;
int totalRows;
// loop region (order/row positions)
struct Position {
@ -195,6 +196,7 @@ struct DivSongTimestamps {
seconds(0), micros(0) {}
};
Timestamp* orders[DIV_MAX_PATTERNS];
Timestamp loopStartTime;
// the furthest row that the playhead goes through in an order.
unsigned char maxRow[DIV_MAX_PATTERNS];

View file

@ -199,6 +199,32 @@ void FurnaceGUI::drawDebug() {
ImGui::Text("patScroll: %f",patScroll);
ImGui::TreePop();
}
if (ImGui::TreeNode("Song Timestamps")) {
if (ImGui::Button("Recalculate")) {
e->calcSongTimestamps();
}
DivSongTimestamps& ts=e->curSubSong->ts;
ImGui::Text("song duration: %d.%06d (%d ticks; %d rows)",ts.totalSeconds,ts.totalMicros,ts.totalTicks,ts.totalRows);
if (ts.isLoopDefined) {
ImGui::Text("loop region is defined");
} else {
ImGui::Text("no loop region");
}
if (ts.isLoopable) {
ImGui::Text("song can loop");
} else {
ImGui::Text("song will stop");
}
ImGui::Text("loop region: %d:%d - %d:%d",ts.loopStart.order,ts.loopStart.row,ts.loopEnd.order,ts.loopEnd.row);
ImGui::Text("loop start time: %d.%06d",ts.loopStartTime.seconds,ts.loopStartTime.micros);
ImGui::Checkbox("Enable row timestamps (in pattern view)",&debugRowTimestamps);
ImGui::TreePop();
}
if (ImGui::TreeNode("Sample Debug")) {
for (int i=0; i<e->song.sampleLen; i++) {
DivSample* sample=e->getSample(i);

View file

@ -8636,6 +8636,7 @@ FurnaceGUI::FurnaceGUI():
audioEngineChanged(false),
settingsChanged(false),
debugFFT(false),
debugRowTimestamps(false),
vgmExportVersion(0x171),
vgmExportTrailingTicks(-1),
vgmExportCorrectedRate(44100),

View file

@ -1726,7 +1726,7 @@ class FurnaceGUI {
bool safeMode;
bool midiWakeUp;
bool makeDrumkitMode;
bool audioEngineChanged, settingsChanged, debugFFT;
bool audioEngineChanged, settingsChanged, debugFFT, debugRowTimestamps;
bool willExport[DIV_MAX_CHIPS];
int vgmExportVersion;
int vgmExportTrailingTicks;

View file

@ -406,6 +406,15 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
for (int k=mustSetXOf; k<=chans; k++) {
patChanX[k]=ImGui::GetCursorScreenPos().x;
}
if (debugRowTimestamps) {
DivSongTimestamps::Timestamp rowTS=e->curSubSong->ts.getTimes(ord,i);
if (rowTS.seconds==-1) {
ImGui::Text("---");
} else {
ImGui::Text("%d.%06d",rowTS.seconds,rowTS.micros);
}
}
}
void FurnaceGUI::drawPattern() {