Chris@30: Chris@30: program generateTemplatesC; Chris@30: Chris@30: vec = load may.vector; Chris@30: Chris@30: instruments = [ Chris@30: "bassoon", Chris@30: "cello", Chris@30: "clarinet", Chris@30: "flute", Chris@30: "guitar", Chris@30: "horn", Chris@30: "oboe", Chris@30: "tenorsax", Chris@30: "violin", Chris@218: "viola", Chris@161: // "piano-maps-SptkBGCl", Chris@161: "piano1", Chris@161: "piano2", Chris@161: "piano3", Chris@218: "pianorwc", Chris@30: ]; Chris@30: Chris@41: hardcodedRanges = [ Chris@41: "bassoon": { lowest = 15, highest = 51 }, Chris@41: "cello": { lowest = 15, highest = 60 }, Chris@41: "clarinet": { lowest = 29, highest = 68 }, Chris@41: "flute": { lowest = 39, highest = 72 }, Chris@41: "guitar": { lowest = 19, highest = 55 }, Chris@41: "horn": { lowest = 20, highest = 56 }, Chris@41: "oboe": { lowest = 37, highest = 70 }, Chris@41: "tenorsax": { lowest = 23, highest = 54 }, Chris@41: "violin": { lowest = 34, highest = 72 }, Chris@161: // "piano-maps-SptkBGCl": { lowest = 16, highest = 72 }, Chris@41: "piano1": { lowest = 16, highest = 72 }, Chris@41: "piano2": { lowest = 16, highest = 72 }, Chris@41: "piano3": { lowest = 16, highest = 72 }, Chris@219: "pianorwc": { lowest = 16, highest = 72 }, Chris@41: ]; Chris@41: Chris@41: overallLowest = 15; Chris@41: overallHighest = 72; Chris@41: Chris@30: dataDir = "../../data"; Chris@30: includeDir = "\(dataDir)/include"; Chris@30: Chris@136: warning = "/* Do not edit: this file was automatically generated by generateTemplatesC */"; Chris@30: Chris@30: noteCount = 88; Chris@30: templateHeight = 545; Chris@44: shiftRange = 2; Chris@30: Chris@30: convert instrument lines ostr = Chris@30: (notes = map do line: Chris@30: vec.fromList (map number (strSplit "," line)) Chris@30: done lines; Chris@30: if (length notes) != noteCount then Chris@30: failWith "Wrong number of notes in instrument \(instrument): found (\(length notes), expected \(noteCount)"; Chris@30: fi; Chris@30: for notes do n: Chris@30: if (vec.length n) != templateHeight then Chris@30: failWith "Wrong number of values in template while processing instrument \(instrument): found \(vec.length n), expected \(templateHeight)"; Chris@30: fi Chris@30: done; Chris@30: levels = map vec.sum notes; Chris@218: first = Chris@218: if instrument in hardcodedRanges then Chris@218: hardcodedRanges[instrument].lowest; Chris@218: else Chris@218: length levels - length (find (>0) levels); Chris@218: fi; Chris@218: last = Chris@218: if instrument in hardcodedRanges then Chris@218: hardcodedRanges[instrument].highest; Chris@218: else Chris@218: length (find (>0) (reverse levels)) - 1; Chris@218: fi; Chris@30: ostr.writeln warning; Chris@30: ostr.writeln ""; Chris@30: ostr.writeln "{\n \"\(instrument)\",\n \(first),\n \(last),"; Chris@30: ostr.writeln " {"; Chris@30: for notes do note: Chris@30: ostr.write " { "; Chris@44: for [0..shiftRange-1] do s: Chris@44: ostr.write "0.0, "; Chris@44: done; Chris@30: for (vec.list note) do v: Chris@30: ostr.write "\(v), "; Chris@30: done; Chris@44: for [0..shiftRange-1] do s: Chris@44: ostr.write "0.0, "; Chris@44: done; Chris@30: ostr.writeln "},"; Chris@30: done; Chris@30: ostr.writeln " }"; Chris@30: ostr.writeln "},"; Chris@30: ostr.close ()); Chris@30: Chris@30: writeMainHeader () = Chris@30: (ostr = openOutFile "\(includeDir)/templates.h" "UTF-8"; Chris@30: for [ Chris@30: warning, Chris@30: "", Chris@30: "#ifndef SILVET_DATA_TEMPLATES_H", Chris@30: "#define SILVET_DATA_TEMPLATES_H", Chris@30: "", Chris@30: "/* note: intended to parse as both C and C++ */", Chris@30: "", Chris@44: "#define SILVET_TEMPLATE_COUNT \(length instruments) /* Number of instruments */", Chris@44: "#define SILVET_TEMPLATE_NOTE_COUNT \(noteCount) /* Number of notes per instrument */ ", Chris@44: "#define SILVET_TEMPLATE_HEIGHT \(templateHeight) /* Frequency bins per template */", Chris@44: "#define SILVET_TEMPLATE_MAX_SHIFT \(shiftRange) /* Zeros at either end of template */ ", Chris@44: "#define SILVET_TEMPLATE_SIZE \(templateHeight + 2 * shiftRange) /* Height + 2 * max shift space */ ", Chris@30: "", Chris@30: "typedef struct {", Chris@30: " const char *name;", Chris@30: " int lowest;", Chris@30: " int highest;", Chris@151: " float data[SILVET_TEMPLATE_NOTE_COUNT][SILVET_TEMPLATE_SIZE];", Chris@30: "} silvet_template_t;", Chris@30: "", Chris@41: "static int silvet_templates_lowest_note = \(overallLowest);", Chris@41: "static int silvet_templates_highest_note = \(overallHighest);", Chris@41: "", Chris@35: "static silvet_template_t silvet_templates[SILVET_TEMPLATE_COUNT] = {", Chris@30: ] ostr.writeln; Chris@30: for instruments do instrument: Chris@30: ostr.writeln "#include \"\(instrument).h\""; Chris@30: done; Chris@30: for [ Chris@30: "};", Chris@30: "", Chris@30: "#endif", Chris@30: ] ostr.writeln; Chris@30: ostr.close ()); Chris@30: Chris@30: convertAll () = Chris@30: (writeMainHeader (); Chris@30: for instruments do instrument: Chris@30: i = openInFile "\(dataDir)/\(instrument).csv" "UTF-8"; Chris@30: o = openOutFile "\(includeDir)/\(instrument).h" "UTF-8"; Chris@30: eprintln "converting instrument \"\(instrument)\"..."; Chris@30: convert instrument (i.lines ()) o; Chris@30: done); Chris@30: Chris@30: convertAll ();