#!/usr/bin/env python2 import sys import midi CLOCK = 1000000.0 MIDIOFF = 16 print "// Music data" print print "uint16_t note_wl[] = {" notes = range(0, 64) wls = [0] + [int(CLOCK / (2 ** ((n + MIDIOFF + 1 - 69) / 12.0) * 440)) for n in notes] print " " + ", ".join(["0x%04x" % wl for wl in wls]) print "};" print mid = midi.read_midifile(sys.argv[1]) data = [] channel = [0, 0, 0] on = set() buf = [] for mev in mid[1]: if mev.tick: buf.sort(lambda a, b: cmp(a.name, b.name)) for ev in buf: if isinstance(ev, midi.NoteOnEvent): note = ev.data[0] - MIDIOFF on.add(note) print "// %s on" % note if note <= 0 or note > 63: print "// DROP" continue for i in range(0, len(channel)): if channel[i] == 0: channel[i] = note data.append((i + 1) << 6 | note) break else: print "// TOO MANY" channel[0] = note data.append(note) elif isinstance(ev, midi.NoteOffEvent): note = ev.data[0] - MIDIOFF on.discard(note) print "// %s off" % note if note <= 0 or note > 63: print "// DROP" continue for i in range(0, len(channel)): if channel[i] == note: channel[i] = 0 data.append((i + 1) << 6) break tlist = list(on) tlist.sort() while len(tlist) > 4: del tlist[1] tick = mev.tick print "// -- %s ticks" % tick while tick > 63: data.append(63) tick -= 63; if tick > 0: data.append(tick) buf = [mev] else: buf.append(mev) #if len(data) > 1000: # break print print "const uint8_t music[] __attribute__ ((section(\".text;\"))) = {" print " " + ", ".join(["0x%02x" % d for d in data]) print "};" print "// " + str(len(data)) + " bytes"