def init_bar(b, quantiz=16): # Note ha i seguenti campi: name, octave, velocity, channel, dynamics dummy = Note('C-0') dummy.velocity = 0 dummy.channel = 0 for j in xrange(quantiz): b.place_notes(dummy, quantiz)
def play_midi(midi_path, save_path, beats, midi_vel, stop_all,midi_device_nr): from mingus.midi import fluidsynth from mingus.containers.note import Note curr_path = lib.os.path.dirname(lib.os.path.abspath(__file__)) fluidsynth.init("/Users/js/Desktop/sounds/Nice-Keys-PlusSteinway-JNv2.0.sf2") f = open(save_path + '/play_midi.csv', 'w+') # open file to save log values f.write('time,beats,midi_note,midi_vel\n') # write first line with corresponding titles mid = lib.mido.MidiFile(midi_path+'.mid') # save parsed MIDI file using mido library s_times = [] # np.zeros((times[0],2)) # create an empty array to storenote events in the MIDI file #port = lib.mido.open_output(lib.mido.get_output_names()[midi_device_nr.value]) # open port to send MIDI messages all_time = 0 # aggregate time for all the messages msg_count = 0 # this is to count MIDI messages with note information all_messages = [] # create an ampty array to only store note information and their position in the score for msg in mid: # for every message in the midi file all_time += msg.time # the file stores midi time based on previous onset, we h if hasattr(msg, 'note'): # checks that the MIDI message is Note #all_time += msg.time # all_messages.append(msg) # adds note message from MIDI file to our playback thing s_times.append([msg_count, all_time]) # array to store note score time msg_count += 1 # count of how many note messages there are in total s_times = lib.np.array(s_times) # convert array to numpy.array yo = lib.copy.deepcopy(s_times) # deepcopy the array so the original doesn't get manipulated while True: if len(yo) != 0: # keep running the loop until there are no more notes to play #print 'here' if yo[0, 1] < beats.value: # if the playhead is larger than the first note in the array play the first note and then delete msgMIDI = all_messages[int(yo[0, 0])] # add note information and it's timing to the midi message to be sent if midi_vel.value > 127: msgMIDI.velocity = 127 else: msgMIDI.velocity = midi_vel.value # add velocity to the MIDI message to be sent f.write( # store values for later analysis "%f, %f, %f, %f\n" % (lib.time.time(), beats.value, all_messages[int(yo[0, 0])].note, midi_vel.value)) msgMIDI.channel = 0 note = Note(all_messages[int(yo[0, 0])].note-12) print note note.velocity = msgMIDI.velocity if msgMIDI.type == 'note_on': fluidsynth.play_Note(note) if msgMIDI.type == 'note_off': fluidsynth.stop_Note(note) #port.send(msgMIDI) # send the message using predefined port (midi device) yo = lib.np.delete(yo, 0, 0) # once the note has been played delete the first message #print beats.value/2 else: # if there are no more notes to play f.close # stop storing the values in csv stop_all.value = True # flag to indicate to the rest of the system that the file has finished. print 'MIDI Playback Finished' # print for use rto acknowledge break
def gen(self, midifilename): dummy = Note('C-0') dummy.velocity = 0 dummy.channel = 9 dummy.duration = self.dur for nb in xrange( self.n_bars ): b = Bar('C', (4,4)) # note "dummy" posizionate su una "griglia di quantizzazione" for i in xrange(self.nsteps): b.place_notes(dummy, self.dur) # print repr(b) # debug # note "vere" for x in self.STRMAP.keys(): ys = self.STRMAP[x] y = self.DRMAP[x] if len(ys) > 0: if len(self.VARMAP[x]) > 0: var = self.VARMAP[x][nb] else: var = 0 if self.vartype == self._OR_VAR_: # or = variazione aggiunge !? xor = toggle tmps = or_str( ys, gen_bin_str(self.nsteps, var) ) elif self.vartype == self._XOR_VAR_: tmps = xor_str( ys, gen_bin_str(self.nsteps, var) ) else: tmps = ys # no var. bin_to_bar(b, y, tmps, self.dur) # cleanup - tolgo le note "dummy" for x in b.bar : x[2].remove_note('C', 0) # print repr(b) # debug self.tk + b # "dummy bar" db = Bar('C', (4,4)) db.place_notes(dummy,1) self.tk + db comp = Composition() comp + self.tk write_Composition(midifilename, comp, self.tempo)
def MIDI_to_Composition(self, file): (header, track_data) = self.parse_midi_file(file) c = Composition() bpm = 120 if header[2]['fps']: print "Don't know how to parse this yet" return c ticks_per_beat = header[2]['ticks_per_beat'] for track in track_data: t = Track() b = Bar() metronome = 1 # Tick once every quarter note thirtyseconds = 8 # 8 thirtyseconds in a quarter note meter = (4, 4) key = 'C' for e in track: (deltatime, event) = e duration = float(deltatime) / (ticks_per_beat * 4.0) if duration != 0.0: duration = 1.0 / duration if len(b.bar) > 0: current_length = b.bar[-1][1] b.bar[-1][1] = duration if current_length - duration != 0: b.current_beat -= 1.0 / current_length b.current_beat += 1.0 / duration if not b.place_notes(NoteContainer(), duration): t + b b = Bar(key, meter) b.place_notes(NoteContainer(), duration) if event['event'] == 8: if deltatime == 0: pass elif event['event'] == 9: # note on n = Note(notes.int_to_note(event['param1'] % 12), event['param1'] / 12 - 1) n.channel = event['channel'] n.velocity = event['param2'] if len(b.bar) > 0: b.bar[-1][2] + n else: b + n elif event['event'] == 10: # note aftertouch pass elif event['event'] == 11: # controller select pass elif event['event'] == 12: # program change i = MidiInstrument() i.instrument_nr = event['param1'] t.instrument = i elif event['event'] == 0x0f: # meta event Text if event['meta_event'] == 1: pass elif event['meta_event'] == 3: # Track name t.name = event['data'] elif event['meta_event'] == 6: # Marker pass elif event['meta_event'] == 7: # Cue Point pass elif event['meta_event'] == 47: # End of Track pass elif event['meta_event'] == 81: # Set tempo warning Only the last change in bpm will get # saved currently mpqn = self.bytes_to_int(event['data']) bpm = 60000000 / mpqn elif event['meta_event'] == 88: # Time Signature d = event['data'] thirtyseconds = self.bytes_to_int(d[3]) metronome = self.bytes_to_int(d[2]) / 24.0 denom = 2**self.bytes_to_int(d[1]) numer = self.bytes_to_int(d[0]) meter = (numer, denom) b.set_meter(meter) elif event['meta_event'] == 89: # Key Signature d = event['data'] sharps = self.bytes_to_int(d[0]) minor = self.bytes_to_int(d[0]) if minor: key = 'A' else: key = 'C' for i in xrange(abs(sharps)): if sharps < 0: key = intervals.major_fourth(key) else: key = intervals.major_fifth(key) b.key = Note(key) else: print 'Unsupported META event', event['meta_event'] else: print 'Unsupported MIDI event', event t + b c.tracks.append(t) return (c, bpm)
def MIDI_to_Composition(self, file): (header, track_data) = self.parse_midi_file(file) c = Composition() if header[2]['fps']: print "Don't know how to parse this yet" return c ticks_per_beat = header[2]['ticks_per_beat'] for track in track_data: t = Track() b = Bar() metronome = 1 # Tick once every quarter note thirtyseconds = 8 # 8 thirtyseconds in a quarter note meter = (4, 4) key = 'C' for e in track: (deltatime, event) = e duration = float(deltatime) / (ticks_per_beat * 4.0) if duration != 0.0: duration = 1.0 / duration if deltatime != 0: if not b.place_notes(NoteContainer(), duration): t + b b = Bar(key, meter) b.place_notes(NoteContainer(), duration) if event['event'] == 8: if deltatime == 0: pass elif event['event'] == 9: # note on n = Note(notes.int_to_note(event['param1'] % 12), event['param1'] / 12 - 1) n.channel = event['channel'] n.velocity = event['param2'] if len(b.bar) > 0: b.bar[-1][2] + n else: b + n elif event['event'] == 10: # note aftertouch pass elif event['event'] == 11: # controller select pass elif event['event'] == 12: # program change i = MidiInstrument() i.instrument_nr = event['param1'] t.instrument = i elif event['event'] == 0x0f: # meta event Text if event['meta_event'] == 1: pass elif event['meta_event'] == 3: # Track name t.name = event['data'] elif event['meta_event'] == 6: # Marker pass elif event['meta_event'] == 7: # Cue Point pass elif event['meta_event'] == 47: # End of Track pass elif event['meta_event'] == 81: # Set tempo warning Only the last change in bpm will get # saved currently mpqn = self.bytes_to_int(event['data']) bpm = 60000000 / mpqn elif event['meta_event'] == 88: # Time Signature d = event['data'] thirtyseconds = self.bytes_to_int(d[3]) metronome = self.bytes_to_int(d[2]) / 24.0 denom = 2 ** self.bytes_to_int(d[1]) numer = self.bytes_to_int(d[0]) meter = (numer, denom) b.set_meter(meter) elif event['meta_event'] == 89: # Key Signature d = event['data'] sharps = self.bytes_to_int(d[0]) minor = self.bytes_to_int(d[0]) if minor: key = 'A' else: key = 'C' for i in xrange(abs(sharps)): if sharps < 0: key = intervals.major_fourth(key) else: key = intervals.major_fifth(key) b.key = Note(key) else: print 'Unsupported META event', event['meta_event'] else: print 'Unsupported MIDI event', event t + b c.tracks.append(t) return (c, bpm)
def MIDI_to_Composition(self, file): (header, track_data) = self.parse_midi_file(file) # print('MIDI_to_Composition:', track_data[1]) # print('===') # print(track_data[2]) # for j in track_data[2]: # if j[1]['event'] == 9 or j[1]['event'] == 8: # print('MIDI_to_Composition:', j[0], j[1]['event'], Note(notes.int_to_note(j[1]['param1'] % 12))) c = Composition() if header[2]['fps']: print("Don't know how to parse this yet") return c ticks_per_beat = header[2]['ticks_per_beat'] for track_idx, track in enumerate(track_data): t = Track() b = Bar() metronome = 1 # Tick once every quarter note thirtyseconds = 8 # 8 thirtyseconds in a quarter note meter = (4, 4) key = 'C' NOTE_ON_counter = 0 for event_idx, e in enumerate(track): (deltatime, event) = e duration = float(deltatime) / (ticks_per_beat * 4.0) if NOTE_ON_counter == 0 and duration != 0 and event['event'] == 9: # then we need to add a rest before playing b.place_rest(1.0/duration) NOTE_ON_counter += 1 # this logic is nice and clear... if duration != 0.0: duration = 1.0 / duration if len(b.bar) > 0: current_length = b.bar[-1][1] b.bar[-1][1] = duration if current_length - duration != 0: b.current_beat -= 1.0 / current_length b.current_beat += 1.0 / duration if not b.place_notes(NoteContainer(), duration): t + b b = Bar(key, meter) b.place_notes(NoteContainer(), duration) if event['event'] == 8: if deltatime == 0: pass elif event['event'] == 9: # note on n = Note(notes.int_to_note(event['param1'] % 12), np.floor(event['param1'] / 12)) # this was event['param1']/12 - 1 but that gives skewed, incorrect octaves n.channel = event['channel'] n.velocity = event['param2'] if len(b.bar) > 0: b.bar[-1][2] + n else: b + n elif event['event'] == 10: # note aftertouch pass elif event['event'] == 11: # controller select pass elif event['event'] == 12: # program change i = MidiInstrument() i.instrument_nr = event['param1'] t.instrument = i elif event['event'] == 0x0f: # meta event Text if event['meta_event'] == 1: pass elif event['meta_event'] == 3: # Track name t.name = event['data'] elif event['meta_event'] == 6: # Marker pass elif event['meta_event'] == 7: # Cue Point pass elif event['meta_event'] == 47: # End of Track pass elif event['meta_event'] == 81: # Set tempo warning Only the last change in bpm will get # saved currently mpqn = self.bytes_to_int(event['data']) bpm = 60000000 / mpqn elif event['meta_event'] == 88: # Time Signature d = event['data'] thirtyseconds = d[3] #self.bytes_to_int(d[3]) metronome = d[2]//24.0 #self.bytes_to_int(d[2]) / 24.0 denom = 2**d[1] #2 ** self.bytes_to_int(d[1]) numer = d[0]#self.bytes_to_int(d[0]) meter = (numer, denom) b.set_meter(meter) elif event['meta_event'] == 89: # Key Signature d = event['data'] sharps = d[0] #self.bytes_to_int(d[0]) minor = d[0] #self.bytes_to_int(d[0]) if minor: key = 'A' else: key = 'C' for i in range(abs(sharps)): if sharps < 0: key = intervals.major_fourth(key) else: key = intervals.major_fifth(key) b.key = Note(key) else: print('Unsupported META event', event['meta_event']) else: print('Unsupported MIDI event', event) t + b c.tracks.append(t) return (c, bpm)