summaryrefslogtreecommitdiff
path: root/tools/tracker_compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/tracker_compiler.cc')
-rw-r--r--tools/tracker_compiler.cc263
1 files changed, 139 insertions, 124 deletions
diff --git a/tools/tracker_compiler.cc b/tools/tracker_compiler.cc
index 491aebb..9f0d6b4 100644
--- a/tools/tracker_compiler.cc
+++ b/tools/tracker_compiler.cc
@@ -1,159 +1,174 @@
#include <cstdio>
#include <fstream>
#include <iostream>
+#include <map>
+#include <sstream>
#include <string>
#include <vector>
-#include <sstream>
-#include <map>
struct Sample {
- std::string name;
- float freq, dur, amp, attack, harmonic_decay;
- int harmonics;
+ std::string name;
+ float freq, dur, amp, attack, harmonic_decay;
+ int harmonics;
};
struct Event {
- float beat;
- std::string sample_name;
- float volume, pan;
+ float beat;
+ std::string sample_name;
+ float volume, pan;
};
struct Pattern {
- std::string name;
- std::vector<Event> events;
+ std::string name;
+ std::vector<Event> events;
};
struct Trigger {
- float time;
- std::string pattern_name;
+ float time;
+ std::string pattern_name;
};
int main(int argc, char** argv) {
- if (argc < 3) {
- std::cerr << "Usage: " << argv[0] << " <input.track> <output.cc>" << std::endl;
- return 1;
- }
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s <input.track> <output.cc>\n", argv[0]);
+ return 1;
+ }
- std::ifstream in(argv[1]);
- if (!in.is_open()) {
- std::cerr << "Could not open input file: " << argv[1] << std::endl;
- return 1;
- }
+ std::ifstream in(argv[1]);
+ if (!in.is_open()) {
+ fprintf(stderr, "Could not open input file: %s\n", argv[1]);
+ return 1;
+ }
- float bpm = 120.0f;
- std::vector<Sample> samples;
- std::map<std::string, int> sample_map;
- std::vector<Pattern> patterns;
- std::map<std::string, int> pattern_map;
- std::vector<Trigger> score;
+ float bpm = 120.0f;
+ std::vector<Sample> samples;
+ std::map<std::string, int> sample_map;
+ std::vector<Pattern> patterns;
+ std::map<std::string, int> pattern_map;
+ std::vector<Trigger> score;
- std::string line;
- std::string current_section = "";
+ std::string line;
+ std::string current_section = "";
- while (std::getline(in, line)) {
- if (line.empty() || line[0] == '#') continue;
+ while (std::getline(in, line)) {
+ if (line.empty() || line[0] == '#')
+ continue;
- std::stringstream ss(line);
- std::string cmd;
- ss >> cmd;
+ std::stringstream ss(line);
+ std::string cmd;
+ ss >> cmd;
- if (cmd == "BPM") {
- ss >> bpm;
- } else if (cmd == "SAMPLE") {
- Sample s;
- std::string name;
- ss >> name;
- if (name.back() == ',') name.pop_back();
- s.name = name;
-
- // Very simple parsing: freq, dur, amp, attack, harmonics, harmonic_decay
- char comma;
- ss >> s.freq >> comma >> s.dur >> comma >> s.amp >> comma >> s.attack >> comma >> s.harmonics >> comma >> s.harmonic_decay;
-
- sample_map[s.name] = samples.size();
- samples.push_back(s);
- } else if (cmd == "PATTERN") {
- Pattern p;
- ss >> p.name;
- current_section = "PATTERN:" + p.name;
- patterns.push_back(p);
- pattern_map[p.name] = patterns.size() - 1;
- } else if (cmd == "SCORE") {
- current_section = "SCORE";
- } else {
- if (current_section.rfind("PATTERN:", 0) == 0) {
- // Parse event: beat, sample, vol, pan
- Event e;
- float beat;
- std::stringstream ss2(line);
- ss2 >> beat;
- char comma;
- ss2 >> comma;
- std::string sname;
- ss2 >> sname;
- if (sname.back() == ',') sname.pop_back();
- e.beat = beat;
- e.sample_name = sname;
- ss2 >> e.volume >> comma >> e.pan;
- patterns.back().events.push_back(e);
- } else if (current_section == "SCORE") {
- Trigger t;
- float time;
- std::stringstream ss2(line);
- ss2 >> time;
- char comma;
- ss2 >> comma;
- std::string pname;
- ss2 >> pname;
- t.time = time;
- t.pattern_name = pname;
- score.push_back(t);
- }
- }
- }
+ if (cmd == "BPM") {
+ ss >> bpm;
+ } else if (cmd == "SAMPLE") {
+ Sample s;
+ std::string name;
+ ss >> name;
+ if (name.back() == ',')
+ name.pop_back();
+ s.name = name;
- std::ofstream out(argv[2]);
- out << "// Generated by tracker_compiler. Do not edit.\n\n";
- out << "#include \"audio/tracker.h\"\n\n";
+ // Very simple parsing: freq, dur, amp, attack, harmonics, harmonic_decay
+ char comma;
+ ss >> s.freq >> comma >> s.dur >> comma >> s.amp >> comma >> s.attack >>
+ comma >> s.harmonics >> comma >> s.harmonic_decay;
- out << "const NoteParams g_tracker_samples[] = {\n";
- for (const auto& s : samples) {
- out << " { " << s.freq << "f, " << s.dur << "f, " << s.amp << "f, " << s.attack << "f, 0.0f, 0.0f, 0.0f, "
- << s.harmonics << ", " << s.harmonic_decay << "f, 0.0f, 0.0f }, // " << s.name << "\n";
+ sample_map[s.name] = samples.size();
+ samples.push_back(s);
+ } else if (cmd == "PATTERN") {
+ Pattern p;
+ ss >> p.name;
+ current_section = "PATTERN:" + p.name;
+ patterns.push_back(p);
+ pattern_map[p.name] = patterns.size() - 1;
+ } else if (cmd == "SCORE") {
+ current_section = "SCORE";
+ } else {
+ if (current_section.rfind("PATTERN:", 0) == 0) {
+ // Parse event: beat, sample, vol, pan
+ Event e;
+ float beat;
+ std::stringstream ss2(line);
+ ss2 >> beat;
+ char comma;
+ ss2 >> comma;
+ std::string sname;
+ ss2 >> sname;
+ if (sname.back() == ',')
+ sname.pop_back();
+ e.beat = beat;
+ e.sample_name = sname;
+ ss2 >> e.volume >> comma >> e.pan;
+ patterns.back().events.push_back(e);
+ } else if (current_section == "SCORE") {
+ Trigger t;
+ float time;
+ std::stringstream ss2(line);
+ ss2 >> time;
+ char comma;
+ ss2 >> comma;
+ std::string pname;
+ ss2 >> pname;
+ t.time = time;
+ t.pattern_name = pname;
+ score.push_back(t);
+ }
}
- out << "};
-";
- out << "const uint32_t g_tracker_samples_count = " << samples.size() << ";\n\n";
+ }
- for (const auto& p : patterns) {
- out << "static const TrackerEvent PATTERN_EVENTS_" << p.name << "[] = {\n";
- for (const auto& e : p.events) {
- out << " { " << e.beat << "f, " << sample_map[e.sample_name] << ", " << e.volume << "f, " << e.pan << "f },\n";
- }
- out << "};
-";
- }
- out << "\n";
+ FILE* out_file = fopen(argv[2], "w");
+ if (!out_file) {
+ fprintf(stderr, "Could not open output file: %s\n", argv[2]);
+ return 1;
+ }
+ fprintf(out_file, "// Generated by tracker_compiler. Do not edit.\n\n");
+ fprintf(out_file, "#include \"audio/tracker.h\"\n\n");
- out << "const TrackerPattern g_tracker_patterns[] = {\n";
- for (const auto& p : patterns) {
- out << " { PATTERN_EVENTS_" << p.name << ", " << p.events.size() << ", 4.0f }, // " << p.name << "\n";
- }
- out << "};
-";
- out << "const uint32_t g_tracker_patterns_count = " << patterns.size() << ";\n\n";
+ fprintf(out_file, "const NoteParams g_tracker_samples[] = {\n");
+ for (const auto& s : samples) {
+ fprintf(out_file,
+ " { %.1ff, %.2ff, %.1ff, %.2ff, 0.0f, 0.0f, 0.0f, %d, %.1ff, "
+ "0.0f, 0.0f }, // %s\n",
+ s.freq, s.dur, s.amp, s.attack, s.harmonics, s.harmonic_decay,
+ s.name.c_str());
+ }
+ fprintf(out_file, "};\n");
+ fprintf(out_file, "const uint32_t g_tracker_samples_count = %zu;\n\n",
+ samples.size());
- out << "static const TrackerPatternTrigger SCORE_TRIGGERS[] = {\n";
- for (const auto& t : score) {
- out << " { " << t.time << "f, " << pattern_map[t.pattern_name] << " },\n";
+ for (const auto& p : patterns) {
+ fprintf(out_file, "static const TrackerEvent PATTERN_EVENTS_%s[] = {\n",
+ p.name.c_str());
+ for (const auto& e : p.events) {
+ fprintf(out_file, " { %.1ff, %d, %.1ff, %.1ff },\n", e.beat,
+ sample_map[e.sample_name], e.volume, e.pan);
}
- out << "};
-\n";
+ fprintf(out_file, "};\n");
+ }
+ fprintf(out_file, "\n");
+
+ fprintf(out_file, "const TrackerPattern g_tracker_patterns[] = {\n");
+ for (const auto& p : patterns) {
+ fprintf(out_file, " { PATTERN_EVENTS_%s, %zu, 4.0f }, // %s\n",
+ p.name.c_str(), p.events.size(), p.name.c_str());
+ }
+ fprintf(out_file, "};\n");
+ fprintf(out_file, "const uint32_t g_tracker_patterns_count = %zu;\n\n",
+ patterns.size());
+
+ fprintf(out_file,
+ "static const TrackerPatternTrigger SCORE_TRIGGERS[] = {\n");
+ for (const auto& t : score) {
+ fprintf(out_file, " { %.1ff, %d },\n", t.time,
+ pattern_map[t.pattern_name]);
+ }
+ fprintf(out_file, "};\n\n");
+
+ fprintf(out_file, "const TrackerScore g_tracker_score = {\n");
+ fprintf(out_file, " SCORE_TRIGGERS, %zu, %.1ff\n", score.size(), bpm);
+ fprintf(out_file, "};\n");
- out << "const TrackerScore g_tracker_score = {\n";
- out << " SCORE_TRIGGERS, " << score.size() << ", " << bpm << "f\n";
- out << "};
-";
+ fclose(out_file);
- return 0;
+ return 0;
}