diff options
Diffstat (limited to 'tools/tracker_compiler.cc')
| -rw-r--r-- | tools/tracker_compiler.cc | 263 |
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; } |
