def midiwrite(filename, piano_roll, r=(21, 109), dt=0.2, patch=0): midi = MidiOutFile(filename) midi.header(division=100) midi.start_of_track() midi.patch_change(channel=0, patch=patch) t = 0 samples = [i.nonzero()[0] + r[0] for i in piano_roll] for i in range(len(samples)): for f in samples[i]: if i == 0 or f not in samples[i - 1]: midi.update_time(t) midi.note_on(channel=0, note=f, velocity=90) t = 0 t += int(dt * 200) for f in samples[i]: if i == len(samples) - 1 or f not in samples[i + 1]: midi.update_time(t) midi.note_off(channel=0, note=f, velocity=0) t = 0 midi.update_time(0) midi.end_of_track() midi.eof()
def writeToMidi(self, filepath, eventTracks=None): if eventTracks == None: eventTracks = self.getEventTracks() midi = MidiOutFile(filepath) midi.header(1, len(self.tracks), 480) # TODO 480? for i in range(len(self.tracks)): track = self.tracks[i] events = eventTracks[i] midi.start_of_track(i) midi.tempo(60000000 / self.tempo) # int(60,000,000.00 / BPM) midi.time_signature(self.beatsPerMeasure, 2, 24, 8) # TODO: ? midi.patch_change(i, track.instrument) lastPos = 0 positions = events.keys() positions.sort() for pos in positions: eventArray = events[pos] deltaPos = pos - lastPos midiTime = int(float(deltaPos) * 300) # TODO: wtf for event in eventArray: midi.update_time(midiTime) pitch = self.noteToPitch(event.note) if event.type == "on": # TODO on/off midi.note_on(channel=i, note=pitch, velocity=event.note.velocity) else: midi.note_off(channel=i, note=pitch) midiTime = 0 # remainder of events are simultaneous lastPos = pos midi.update_time(0) midi.end_of_track() midi.eof()
def toFile(self, filename): print "to file", filename self.events = sorted(self.events, key=itemgetter(3, 0)) # count number of unique tracks tracks = list(set([i[0] for i in self.events])) midi_out = MidiOutFile(filename) midi_out.header(nTracks=len(tracks), division=self.ppq) for i in tracks: midi_out.start_of_track(i) midi_out.patch_change(self.channelForTrack[i], self.patchForTrack[i]) midi_out.update_time(0,relative=False) nl=[] # for this track, build a note list for t,p,s,d,v,channel,patch in [x[1:] for x in self.events if x[0] == i]: if t == 'note': print "on", (0,p,s,v,channel,patch) print "off", (1,p,s+d,0,channel,patch) nl.append((0,p,s,v,channel,patch)) nl.append((1,p,s+d,0,channel,patch)) elif t == 'tempo': nl.append((2,p,s,0,channel,patch)) # for this track, sort the note list by start time and send it to midi file writer # t is for type for t,p,s,v,channel,patch in sorted(nl,key=itemgetter(2)): midi_out.update_time(int(s*1000), relative=False) if t == 0: midi_out.note_on(channel=self.channelForTrack[i], note=p, velocity=v) #print "note on event" elif t == 1: midi_out.note_off(channel=self.channelForTrack[i], note=p) elif t == 2: print "tempo event" midi_out.tempo(p) midi_out.end_of_track() midi_out.eof()
def generate_midi_file(self): (f, path) = tempfile.mkstemp() os.close(f) midi = MidiOutFile(path) # parts per quarter-note PPQ = 96 # parts per down-beat ppd = int(PPQ * 4.0 / self.timesig_denom) class __Helper: def __init__(self, feel, ppd): self.feel = feel self.ppd = ppd self.default_dur = self.ppd if self.feel == FEEL_STRAIGHT: self.default_dur = self.ppd / 2 elif self.feel == FEEL_TRIPLET: self.default_dur = self.ppd / 3 elif self.feel == FEEL_SWING: self.default_dur = self.ppd / 3 self.last_note = 0 self.dur_remaining = 0 def write_note(self, note, dur=None, rest=False): if rest: self.write_rest(dur) return if dur == None: dur = self.default_dur dur = max(0, dur) midi.note_on(channel=1, note=note) midi.update_time(dur) self.last_note = note self.dur_remaining -= dur def write_rest(self, dur=None): if dur == None: dur = self.default_dur dur = max(0, dur) midi.note_off(channel=1, note=self.last_note) midi.update_time(dur) self.dur_remaining -= dur def reset_downbeat(self): self.write_rest(self.dur_remaining) self.dur_remaining = self.ppd def write_accent(self, dur=None, rest=False): self.reset_downbeat() self.write_note(0x50, dur, rest) def write_downbeat(self, dur=None, rest=False): self.reset_downbeat() self.write_note(0x4C, dur, rest) def write_upbeat(self, dur=None, rest=False): self.write_note(0x4A, dur, rest) def write_feelbeats(self): if self.feel == FEEL_STRAIGHT: self.write_upbeat(self.dur_remaining) elif self.feel == FEEL_TRIPLET: self.write_upbeat() self.write_upbeat(self.dur_remaining) elif self.feel == FEEL_SWING: helper.write_rest() self.write_upbeat(self.dur_remaining) helper = __Helper(self.feel, ppd) del __Helper # Create sections # section_list = [] class Section: def __init__(self): self.measures = 0 def write(self): pass class FullSection(Section): def __init__(self, timesig_numer): self.measures = 1 self.timesig_numer = timesig_numer def write(self): for i in range(self.timesig_numer): if i == 0: helper.write_accent() else: helper.write_downbeat() helper.write_feelbeats() section_list.append(FullSection(self.timesig_numer)) class DownbeatSection(Section): def __init__(self, timesig_numer, downbeat_count): self.measures = 1 self.timesig_numer = timesig_numer self.downbeat_count = downbeat_count def write(self): for i in range(self.timesig_numer): if i == 0: helper.write_accent() else: helper.write_downbeat() if i < self.downbeat_count: helper.write_feelbeats() for i in reversed(range(self.timesig_numer)): section_list.append(DownbeatSection(self.timesig_numer, i)) class AccentSection(Section): def __init__(self, timesig_numer, downbeat_count): self.measures = 1 self.timesig_numer = timesig_numer self.downbeat_count = downbeat_count def write(self): for i in range(self.timesig_numer): if i == 0: helper.write_accent() else: helper.write_downbeat(rest=(i >= self.downbeat_count)) for i in reversed(range(1, self.timesig_numer)): section_list.append(AccentSection(self.timesig_numer, i)) # non optional midi framework midi.header(format=0, nTracks=1, division=PPQ) midi.start_of_track() midi.sequence_name('Percussion') midi.instrument_name('Percussion') midi.patch_change(channel=1, patch=115) midi.update_time(0) # non-musical events # timesig_denom_exp = int(math.log(self.timesig_denom, 2)) midi.time_signature(self.timesig_numer, timesig_denom_exp, 24, 8) midi.tempo(int(60000000.00 / float(self.tempo))) # musical events # minutes_per_measure = self.timesig_numer / float(self.tempo) * 4.0 / self.timesig_denom total_minutes = 0 section_count = 0 while total_minutes < self.duration: section = section_list[section_count % len(section_list)] for i in range(0, self.measures_per_phrase, section.measures): section.write() total_minutes += minutes_per_measure section_count += 1 # non optional midi framework midi.update_time(0) midi.end_of_track() # not optional! midi.eof() file = open(path) self.midi_file.save(None, File(file)) file.close() os.remove(path)
result = "" for gn in selection: result += gn return result s = CurrentFont().selection out_file = 'midi_out/%s-%s_%s.mid' % (CurrentFont().info.familyName, CurrentFont().info.styleName , getSelectionName(s)) out_file = 'midi_out/%s-%s_%s.mid' % ("Nimbus", "Sans", getSelectionName(s)) midi = MidiOutFile(out_file) # non optional midi framework midi.header(format=1, nTracks=1, division=1024) midi.start_of_track() midi.tempo(int(60000000.0/140)) midi.patch_change(0, 1) # musical events pen = MidiPen() for gn in s: g =CurrentFont()[gn] midi.sequence_name(gn) midi.note_on(channel=9, note=36) midi.update_time(0) midi.note_off(channel=9, note=36) midi.update_time(0) g.draw(pen) print gn,