summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--assets/demo.seq4
-rw-r--r--tools/seq_compiler.cc141
3 files changed, 144 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 5bddfa0..5050a88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,3 +62,4 @@ compile_commands.json
*.spec
*.aif
*.wav
+demo_timeline.txt
diff --git a/assets/demo.seq b/assets/demo.seq
index fced9d6..833e5f7 100644
--- a/assets/demo.seq
+++ b/assets/demo.seq
@@ -4,6 +4,10 @@
# This file defines the timeline and layering of visual effects.
# Compiled by seq_compiler into src/generated/timeline.cc at build time.
#
+# DEBUGGING: Generate a Gantt chart visualization of the timeline:
+# ./build/seq_compiler assets/demo.seq src/generated/timeline.cc --gantt=timeline.txt
+# The chart shows sequences and effects on a time axis with labels.
+#
# BPM 120
#
#
diff --git a/tools/seq_compiler.cc b/tools/seq_compiler.cc
index a4fd00c..548f467 100644
--- a/tools/seq_compiler.cc
+++ b/tools/seq_compiler.cc
@@ -32,6 +32,131 @@ std::string trim(const std::string& str) {
return str.substr(first, (last - first + 1));
}
+// Generate ASCII Gantt chart for timeline visualization
+void generate_gantt_chart(const std::string& output_file,
+ const std::vector<SequenceEntry>& sequences,
+ float bpm, const std::string& demo_end_time) {
+ std::ofstream out(output_file);
+ if (!out.is_open()) {
+ std::cerr << "Warning: Could not open Gantt chart output file: " << output_file << "\n";
+ return;
+ }
+
+ // Find max time for the chart
+ float max_time = demo_end_time.empty() ? 0.0f : std::stof(demo_end_time);
+ for (const auto& seq : sequences) {
+ float seq_start = std::stof(seq.start_time);
+ for (const auto& eff : seq.effects) {
+ float eff_end = seq_start + std::stof(eff.end);
+ max_time = std::max(max_time, eff_end);
+ }
+ if (seq.end_time != "-1.0") {
+ max_time = std::max(max_time, seq_start + std::stof(seq.end_time));
+ }
+ }
+
+ // Chart configuration
+ const int chart_width = 100;
+ const float time_scale = chart_width / max_time;
+
+ out << "Demo Timeline Gantt Chart\n";
+ out << "==============================================================================\n";
+ out << "BPM: " << bpm << ", Duration: " << max_time << "s";
+ if (!demo_end_time.empty()) {
+ out << " (explicit end)";
+ }
+ out << "\n\n";
+
+ // Time axis header
+ out << "Time (s): ";
+ for (int i = 0; i <= (int)max_time; i += 5) {
+ out << i;
+ int spacing = (i < 10) ? 4 : (i < 100) ? 3 : 2;
+ if (i + 5 <= max_time) {
+ for (int j = 0; j < spacing; ++j) out << " ";
+ }
+ }
+ out << "\n";
+ out << " ";
+ for (int i = 0; i < chart_width; ++i) {
+ if (i % 5 == 0) out << "|";
+ else out << "-";
+ }
+ out << "\n\n";
+
+ // Draw sequences and effects
+ for (const auto& seq : sequences) {
+ float seq_start = std::stof(seq.start_time);
+ float seq_end = max_time; // Default: runs until end
+
+ // Check if sequence has explicit end time
+ if (seq.end_time != "-1.0") {
+ seq_end = seq_start + std::stof(seq.end_time);
+ } else {
+ // Calculate implicit end from latest effect
+ for (const auto& eff : seq.effects) {
+ seq_end = std::max(seq_end, seq_start + std::stof(eff.end));
+ }
+ }
+
+ // Draw sequence bar
+ out << "SEQ@" << seq_start << "s [pri=" << seq.priority << "]";
+ if (seq.end_time != "-1.0") {
+ out << " [END=" << seq_end << "s]";
+ }
+ out << "\n";
+
+ int start_col = (int)(seq_start * time_scale);
+ int end_col = (int)(seq_end * time_scale);
+ out << " ";
+ for (int i = 0; i < chart_width; ++i) {
+ if (i >= start_col && i < end_col) out << "█";
+ else out << " ";
+ }
+ out << " (" << seq_start << "-" << seq_end << "s)\n";
+
+ // Draw effects within sequence
+ for (const auto& eff : seq.effects) {
+ float eff_start = seq_start + std::stof(eff.start);
+ float eff_end = seq_start + std::stof(eff.end);
+
+ // Truncate if sequence has explicit end time
+ if (seq.end_time != "-1.0") {
+ eff_end = std::min(eff_end, seq_end);
+ }
+
+ out << " " << eff.class_name << " [pri=" << eff.priority << "]";
+ if (eff_end < eff_start) {
+ out << " *** INVALID TIME RANGE ***";
+ }
+ out << "\n";
+ out << " ";
+
+ int eff_start_col = (int)(eff_start * time_scale);
+ int eff_end_col = (int)(eff_end * time_scale);
+
+ for (int i = 0; i < chart_width; ++i) {
+ if (i >= eff_start_col && i < eff_end_col) {
+ out << "▓";
+ } else if (i >= start_col && i < end_col) {
+ out << "·"; // Show sequence background
+ } else {
+ out << " ";
+ }
+ }
+ out << " (" << eff_start << "-" << eff_end << "s)\n";
+ }
+ out << "\n";
+ }
+
+ out << "==============================================================================\n";
+ out << "Legend: █ Sequence ▓ Effect · Sequence background\n";
+ out << "Priority: Higher numbers render later (on top)\n";
+
+ out.close();
+ std::cout << "Gantt chart written to: " << output_file << "\n";
+}
+
// Convert beat notation to time in seconds
// Supports: "64b" or "64" (beats), "32.0s" or "32.0" with decimal point (seconds)
std::string convert_to_time(const std::string& value, float bpm) {
@@ -63,13 +188,20 @@ std::string convert_to_time(const std::string& value, float bpm) {
}
int main(int argc, char* argv[]) {
- if (argc != 3) {
- std::cerr << "Usage: " << argv[0] << " <input.seq> <output.cc>\n";
+ if (argc < 3 || argc > 4) {
+ std::cerr << "Usage: " << argv[0] << " <input.seq> <output.cc> [--gantt <gantt.txt>]\n";
std::cerr << "Example: " << argv[0]
<< " assets/demo.seq src/generated/timeline.cc\n";
+ std::cerr << " " << argv[0]
+ << " assets/demo.seq src/generated/timeline.cc --gantt timeline.txt\n";
return 1;
}
+ std::string gantt_output = "";
+ if (argc == 4 && std::string(argv[3]).rfind("--gantt=", 0) == 0) {
+ gantt_output = std::string(argv[3]).substr(8); // Extract filename after --gantt=
+ }
+
std::ifstream in_file(argv[1]);
if (!in_file.is_open()) {
std::cerr << "Error: Could not open input file " << argv[1] << "\n";
@@ -248,5 +380,10 @@ int main(int argc, char* argv[]) {
std::cout << "Successfully generated timeline with " << sequences.size()
<< " sequences.\n";
+ // Generate Gantt chart if requested
+ if (!gantt_output.empty()) {
+ generate_gantt_chart(gantt_output, sequences, bpm, demo_end_time);
+ }
+
return 0;
}