def roll2midi(roll, notesMap, reductionRatio=128): #roll is a (1, ts, input_dim) tensor mid = MidiFile() track = MidiTrack() mid.tracks.append(track) tones = np.zeros(roll.shape[1]) ticks = 0 for ts in roll: for i in range(ts.shape[0]-1): if ts[i] == 1 and tones[i] == 0: #record note_on event track.append(Message('note_on', velocity=127, note=notesMap[i], time=ticks*reductionRatio)) tones[i] = 1 ticks = 0 if ts[i] == 0 and tones[i] == 1: #record note_off event track.append(Message('note_off', velocity=127, note=notesMap[i], time=ticks*reductionRatio)) tones[i] = 0 ticks = 0 ticks += 1 #last pass for notes off (end of track) for i in range(roll.shape[1]): if tones[i] == 1: track.append(Message('note_off', note=notesMap[i], time=ticks*reductionRatio)) ticks = 0 return mid
def output_messages(filename, messages): # Takes the name of a MIDI file to create and fill with the list of messages. # Returns nothing. with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) for message in messages: track.append(message) outfile.save(filename)
def _instrument_change(self, track: MidiTrack, channel: int = 0, instrument: int = 0, time: int = 0): track.append( Message("program_change", channel=channel, program=instrument, time=time))
def output_messages(filename, *messages): # Takes the name of a MIDI file to create and fill with the list of messages. # Returns nothing. with MidiFile() as outfile: for message_track in messages: track = MidiTrack() outfile.tracks.append(track) for message in message_track: track.append(message) outfile.save(filename)
def updateValue(midiFileInput): midiFileToReturn = MidiFile() for i,element in enumerate(midiFileInput.tracks): tmpTrack = MidiTrack() midiFileToReturn.tracks.append(tmpTrack) for msg in element: msg.time = int(msg.time) print("track" + str(msg.time)) tmpTrack.append(msg) return midiFileToReturn
def messages_to_midifile(messages): """ creates MidiFile with given messages """ outfile = MidiFile() track = MidiTrack() outfile.tracks.append(track) for msg in messages: track.append(msg) return outfile
def pitchstream_to_midi(pitchstreams): """Convert pitchstream to a MIDI file.""" midi = MidiFile() ticks_per_beat = 300 if len(pitchstreams[0]) > 1: # More than one instruments in the track tracks = [MidiTrack() for track in range(len(pitchstreams[0]))] previous_pitches = [0] * len(pitchstreams[0]) for track in tracks: midi.tracks.append(track) for pitchstream in pitchstreams: for i, pitches in enumerate(pitchstream): tracks[i].append(MidiMessage(type='note_on', note=0, velocity=0, time=0)) if pitches != '0': tracks[i].append(MidiMessage(type='note_on', note=pitches, velocity=127, time=ticks_per_beat)) previous_pitches[i] = pitches elif pitches != previous_pitches[i]: tracks[i].append(MidiMessage(type='note_off', note=previous_pitches[i], velocity=0, time=0)) previous_pitches[i] = pitches else: # Only one instrument in the track track = MidiTrack() midi.tracks.append(track) track.append(MidiMessage(type='note_on', note=0, velocity=0, time=0)) for pitch in pitchstreams: if pitch != '0': track.append(MidiMessage(type='note_on', note=pitch, velocity=127, time=ticks_per_beat)) previous_pitch = pitch elif pitch != previous_pitch: track.append(MidiMessage(type='note_off', note=previous_pitch, velocity=0, time=0)) previous_pitch = pitch return midi
def generateSingleNoteMidi(filename, instrument, note): mid = MidiFile() track = MidiTrack() mid.tracks.append(track) mid.ticks_per_beat = 32 velocity = 70 track.append(Message('program_change', program=instrument, time=0)) track.append(MetaMessage('set_tempo', tempo=1000000, time=0)) track.append(Message('note_on', note=note, velocity=velocity, time=0)) track.append(Message('note_off', note=note, velocity=127, time=32)) mid.save(filename)
def write_tracks(events): """ Creates midi file from event list :param events: midi events as a list of NoteUpEvent, NoteDownEvent, DtEvent :return: MidiFile with the track """ mid = MidiFile(ticks_per_beat=384) #480 # tempo track controls conversion of ticks in sec tempo_track = MidiTrack() mid.tracks.append(tempo_track) tempo = 500000 tempo_track.append(MetaMessage("set_tempo", tempo=tempo, time=0)) # melody track mel_track = MidiTrack() mid.tracks.append(mel_track) last_dt = 0 rounding_error = 0 velocity = 64 for event in events: if isinstance(event, DtEvent): last_dt += event.dt if isinstance(event, VelocityEvent): velocity = event.vel if isinstance(event, NoteDownEvent): delta_ticks = int( mido.second2tick(last_dt, mid.ticks_per_beat, tempo)) mel_track.append( Message("note_on", note=event.note, time=delta_ticks, velocity=velocity)) last_dt = 0 rounding_error += abs( delta_ticks - mido.second2tick(last_dt, mid.ticks_per_beat, tempo)) if isinstance(event, NoteUpEvent): delta_ticks = int( mido.second2tick(last_dt, mid.ticks_per_beat, tempo)) mel_track.append( Message("note_off", note=event.note, time=delta_ticks)) last_dt = 0 rounding_error += abs( delta_ticks - mido.second2tick(last_dt, mid.ticks_per_beat, tempo)) print(rounding_error) return mid
def build_melody(scale, tracks, note_deviance, beat, max_length, rand_beat, velocity, rests, save_path): """A function to create a single track midi object. Default is 120bpm. Args: - scale (list): list of 'allowable' notes - tracks (int): how many voices, as separate tracks, in the midi file? - note_deviance (float): the probability that a note is altered by a half-step - beat (int): beat length value of a 'quarter note' at 120bpm, 480 represents a 'regular' quarter note. - max_length (int): the maximum number of 'beats' as defined above of the entire phrase. phrase may be shorter. - rand_beat (bool): should the beats be randon (True), or uniform (False)? - velocity (int): velocity of the midi notes - rests (bool): if true output will contain random offsets in note start position - save_path (str): what to name the file """ # (synchronous): all tracks start at the same time mid = MidiFile(type=1) for v in range(tracks): track = MidiTrack() mid.tracks.append(track) timings = get_timings(beat, max_length, rand_beat) melody = gen_melody(scale, timings, note_deviance) if rests == True: t = 0 for note, timing in zip(melody, timings): track.append( Message('note_on', note=note, velocity=velocity, time=t)) track.append( Message('note_off', note=note, velocity=velocity, time=timing + t)) t += timing else: for note, timing in zip(melody, timings): track.append( Message('note_on', note=note, velocity=velocity, time=0)) track.append( Message('note_off', note=note, velocity=velocity, time=timing + 0)) mid.save(save_path)
def __init__(self, port, device_id, tempo=120, debug=True): self.port = port self.on_id = device_id self.tempo = tempo self.debug = debug self.__mid = MidiFile() self.__track = MidiTrack() self.__mid.tracks.append(self.__track) #self.prepareTrack() self.__activesense = 0
def clean_midi(mid): """ remove everything but note_on, note_off """ new_mid = MidiFile() for track in mid.tracks: new_track = MidiTrack() for msg in track: if msg.type in ['note_on', 'note_off'] and msg.channel != 9: new_track.append(msg) new_mid.tracks.append(new_track[:]) return new_mid
def __init__(self, csv_file, deltaT): self.deltaT = deltaT self.csv_file = csv_file # default values cause yolo self.ticks_per_beat = 384 self.tempo = 512820 self.active_notes = [None] * 127 self.mid = MidiFile(ticks_per_beat=self.ticks_per_beat) self.track = MidiTrack() self.mid.tracks.append(self.track) self.set_meta_tempo() self.last_note_time = 0
class FileOutputStream(FileStream): def __init__(self, config): super(FileOutputStream, self).__init__(config) self.output_file = MidiFile() self.track = MidiTrack() self.output_file.tracks.append(self.track) def send(self, message): self.track.append(message) def close(self): self.output_file.save(self.pathname)
def _write_note_off(self, track: MidiTrack, channel: int = 0, note: int = 60, velocity: int = 64, time: int = 0): track.append( Message("note_off", channel=channel, note=note, velocity=velocity, time=time))
def add_message(self, track: mido.MidiTrack, note: int, time: int, msg="note_on") -> mido.MidiTrack: """ Appends the message of type `msg` for the given `note` at the given `time` to the `track`. Returns the modified track. """ msg = mido.Message(msg, note=note, time=int(time)) track.append(msg) return track
def updateValue(midiFileInput): midiFileToReturn = MidiFile() for element in midiFileInput.tracks: tmpTrack = MidiTrack() midiFileToReturn.tracks.append(tmpTrack) for msg in element: if (msg.type == 'time_signature'): msg.numerator = 4 msg.denominator = 4 msg.time = msg.time tmpTrack.append(msg) return midiFileInput
def _generate_header_track(tempo): midit = MidiTrack() midit.append( MetaMessage("time_signature", numerator=4, denominator=4, clocks_per_click=24, notated_32nd_notes_per_beat=8, time=0)) midit.append(MetaMessage("set_tempo", tempo=int(tempo / 2), time=0)) midit.append(MetaMessage("copyright", text=SIGNATURE)) midit.append(MetaMessage("end_of_track", time=1)) return midit
class RecordHandler: def __init__(self): self.recording = None self.timer_record_midi = None self.file = None self.track = None self.tempo = None def start(self): self.track = MidiTrack() self.file = MidiFile() self.file.tracks.append(self.track) self.tempo = time() def stop(self): if self.file: del self.track[0] del self.track[-1] Path("{}/{}".format( MIDI_RECORD_SAVE_DIRECTORY, datetime.now().strftime(MIDI_RECORD_SAVE_FOLDER_FORMAT), )).mkdir(parents=True, exist_ok=True) filename = "{}/{}/{}.mid".format( MIDI_RECORD_SAVE_DIRECTORY, datetime.now().strftime(MIDI_RECORD_SAVE_FOLDER_FORMAT), datetime.now().strftime(MIDI_RECORD_SAVE_TIME_FORMAT), ) self.file.save(filename=filename) self.file = None def process(self, msg): if msg.type == "note_on": type = "note_on" if msg.velocity > 0 else "note_off" self.track.append( Message( type, note=msg.note, velocity=msg.velocity, time=int((time() - self.tempo) * MIDI_TEMPO_MULTIPLIER), )) if msg.type == "control_change": self.track.append( Message( "control_change", control=64, value=msg.value, time=int((time() - self.tempo) * MIDI_TEMPO_MULTIPLIER), )) self.tempo = time()
def merge_midi(midis, input_dir, output, default_tempo=500000): '''Merge midi files into one''' pairs = [(int(x[:-4].split('_')[-1]), x) for x in midis] pairs = sorted(pairs, key=lambda x: x[0]) midis = [join(input_dir, x[1]) for x in pairs] mid = MidiFile(midis[0]) # identify the meta messages metas = [] # tempo = default_tempo tempo = default_tempo // 2 for msg in mid: if msg.type is 'set_tempo': tempo = msg.tempo if msg.is_meta: metas.append(msg) for meta in metas: meta.time = int(mido.second2tick(meta.time, mid.ticks_per_beat, tempo)) target = MidiFile() track = MidiTrack() track.extend(metas) target.tracks.append(track) for midi in midis: mid = MidiFile(midi) for msg in mid: if msg.is_meta: continue if msg.type is not 'end_of_track': msg.time = int( mido.second2tick(msg.time, mid.ticks_per_beat, tempo)) track.append(msg) track.append(MetaMessage('end_of_track')) target.save(output)
def df_to_midi(dfc, ticks_per_beat, filename): """ Function to write midi dataframes returned by midi_to_df() back to a midi file :param dfc: dataframe containing the meta event information returned by midi_to_df :type dfc: pandas.DataFrame :param ticks_per_beat: integer containing the ticks_per_beat information returned by mido.MidiFile :type ticks_per_beat: integer :param filename: string containing the name of the midi file to be written :type filename: string """ outfile = MidiFile() outfile.ticks_per_beat = ticks_per_beat track = MidiTrack() outfile.tracks.append(track) for index, row in dfc.iterrows(): if row['meta'] == True: if row['msg']['type'] == 'track_name': track = MidiTrack() outfile.tracks.append(track) track.append(MetaMessage(**row['msg'])) else: track.append(Message(**row['msg'])) outfile.save(filename)
def convert_midi(self): mid = MidiFile() track = MidiTrack() mid.tracks.append(track) curr_on = [] for fft_sample in self.n: for i, note in enumerate(curr_on): if i == 0: track.append( Message('note_off', note=note, velocity=0, time=100)) else: track.append( Message('note_off', note=note, velocity=0, time=0)) curr_on = [] for freq in fft_sample: note_freq = freq[0] note_amplitude = 2.0 * self.timestep * freq[1] if note_amplitude > 0.01 and note_freq > 10: midi_note = 69 + (math.log(note_freq / 440.0, 2) * 12) midi_note = int(midi_note) if midi_note > 5: curr_on.append(midi_note) track.append( Message('note_on', note=midi_note, velocity=int( np.abs(note_amplitude) * 80.0), time=0)) mid.save('output.mid')
def combine_tracks(metadata, instrument_tracks): """ Combines array of instruments to MidiFile object :param instrument_tracks: array of instruments metadata: metadata of the conditioning file so that the output is in the same style and key :return MidFile object: """ mid = MidiFile() header = [] for data in metadata: for msg in data: if msg.type == 'smpte_offset' or msg.type == 'time_signature' or msg.type == 'key_signature'\ or msg.type == 'set_tempo': header.append(data) break for data in header: track = MidiTrack() mid.tracks.append(track) for elements in data: track.append(elements) for data in instrument_tracks: track = MidiTrack() mid.tracks.append(track) for elements in data: track.append(elements) return mid
def write_midi_from_series(series, midi_program, output_path): outfile = MidiFile() step_size = int(outfile.ticks_per_beat / 8) track = MidiTrack() outfile.tracks.append(track) track.append(Message('program_change', program=midi_program)) delta = 0 for i in range(len(series[0])): for j in range(len(series)): note = series[j, i] if note > 20: # this is to prevent low signals from filtering in #print(note) track.append( Message('note_on', note=note, velocity=100, time=delta)) delta = 0 delta = delta + step_size track.append(MetaMessage('end_of_track')) print("Creating midi file: ", output_path, " from series") outfile.save(output_path)
def to_midi_track(self): """Converts this track to MidiTrack from mido""" track = MidiTrack() track.append(MetaMessage('set_tempo', tempo=bpm2tempo(self.bpm))) # dont yet know what this does track.append( Message('program_change', program=self.instrument.value, time=0, channel=self.channel)) preprocessed_events = self.__preprocess_events() last_tick = 0 for event in preprocessed_events: time_diff = event.tick - last_tick last_tick = event.tick track.append( Message( 'note_on' if event.type == 'start' else 'note_off', note=event.note, velocity=64, time=time_diff, channel=self.channel, )) return track
def convert_grid_to_midi(grid, ticks_per_beat, tempo): # create blank MIDI file and track m = MidiFile(type=0, ticks_per_beat=ticks_per_beat) trk = MidiTrack() m.tracks.append(trk) trk.append(MetaMessage('set_tempo', tempo=tempo)) # add padding zeros at beginning and end of sample to allow calculation of on and off messages grid = np.concatenate((np.zeros((1, 128)), grid, np.zeros((1, 128)))) t_last_event = 0 # iterate over sample and compare notes on/off at time t and t+1 for t in range(grid.shape[0] - 1): for pitch in range(grid.shape[1]): change = grid[t + 1, pitch] - grid[t, pitch] if change == 1: trk.append( Message('note_on', note=pitch, time=(t - t_last_event), velocity=100)) t_last_event = t if change == -1: trk.append( Message('note_off', note=pitch, time=(t - t_last_event))) t_last_event = t return m
def createMidi(notes): new_song = MidiFile(ticks_per_beat=2, type=0) track = MidiTrack() new_song.tracks.append(track) for note in notes: len_str, note_num = note note_len = notes_len_dict[len_str] print('Note: %d Length: %d' % (note_num, note_len)) msg = Message('note_on', note=note_num, time=note_len) track.append(msg) new_song.save('song.mid')
def play_midi_events(events, filelabel=0, program_number=0): COMP_CHANNEL = 5 beats_per_bar = 4 ticks_per_beat = 24 mid = MidiFile() track = MidiTrack() mid.tracks.append(track) track.append( Message('program_change', channel=COMP_CHANNEL, program=program_number)) for tick_event in events: for msg in tick_event: track.append(msg.copy(channel=COMP_CHANNEL, time=0)) # This effectively acts as a time.sleep for 1 tick track.append(Message('note_off', note=0, velocity=0, time=16)) FILEPATH = '/tmp/tmp_' + filelabel MIDIPATH = FILEPATH + '.mid' WAVPATH = FILEPATH + '.wav' mid.save(MIDIPATH) return_code = subprocess.call( "timidity --adjust-tempo=80 {} -Ow -o {}".format(MIDIPATH, WAVPATH), shell=True) if return_code == 0: return WAVPATH else: return return_code
def one_hot_to_midi(one_hot, midi_filename='song.mid'): mid = MidiFile() track = MidiTrack() mid.tracks.append(track) pitch = 36 duration = 128 velocity = 64 track.append(Message('program_change', program=12, time=0)) #for sb in one_hot: for i in range(one_hot.shape[1]): sb = one_hot[:, i] pitch = int(index_to_pitch(np.argmax(sb))) track.append( Message('note_on', channel=9, note=pitch, velocity=64, time=duration)) track.append( Message('note_off', channel=9, note=pitch, velocity=127, time=duration)) mid.save(midi_filename)
def MatrixToMidi(self, matrixPiano, filepath): # ensure that resolution is an integer ticks_per_time_slice = 1 tempo = 1 / self.time_per_time_slice resolution = 60 * ticks_per_time_slice / (tempo * self.time_per_time_slice) mid = MidiFile(ticks_per_beat=int(resolution)) track = MidiTrack() mid.tracks.append(track) track.append( MetaMessage('set_tempo', tempo=int(self.MICROSECONDS_PER_MINUTE / tempo), time=0)) current_state = np.zeros(self.input_dim) index_of_last_event = 0 for slice_index, time_slice in enumerate( np.concatenate((matrixPiano, np.zeros((1, self.input_dim))), axis=0)): note_changes = time_slice - current_state for note_idx, note in enumerate(note_changes): if note == 1: note_event = Message( 'note_on', time=(slice_index - index_of_last_event) * ticks_per_time_slice, velocity=65, note=note_idx + self.lowest_note) track.append(note_event) index_of_last_event = slice_index elif note == -1: note_event = Message( 'note_off', time=(slice_index - index_of_last_event) * ticks_per_time_slice, velocity=65, note=note_idx + self.lowest_note) track.append(note_event) index_of_last_event = slice_index current_state = time_slice eot = MetaMessage('end_of_track', time=1) track.append(eot) mid.save(filepath)
def convertEncodedMessagesToMIDI(msgs, filename): from mido import Message, MidiFile, MidiTrack mid = MidiFile() track = MidiTrack() mid.tracks.append(track) mid.ticks_per_beat = 96 for (note, velocity, pedal_value, dt) in msgs: time = int(mido.second2tick(dt, mid.ticks_per_beat, 500000)) if time < 0: time = 0 if note == 0: track.append( Message('control_change', control=64, value=midiClamp(pedal_value * 127.0), time=time)) else: note -= 1 if note % 2 == 1: track.append( Message('note_on', note=note / 2 + 21, velocity=0, time=time)) else: track.append( Message('note_on', note=note / 2 + 21, velocity=midiClamp(velocity * 127.0), time=time)) mid.save(filename)
def apply_mutation(mutantnotelist, midino, snote=50, time=150, filename='random'): mid = MidiFile(type=0) # type0 can have only one track track = MidiTrack() # note list (kind of) mid.tracks.append(track) # Create mutant music folder if it does not exist if not os.path.exists('mutantmusic'): os.makedirs('mutantmusic') # add the octaves back mutantnotelist2 = [x+snote for x in mutantnotelist] for note in mutantnotelist2[:len(mutantnotelist2)-2]: #print(note) track.append(Message('note_on', note=int(note), velocity = 127, time=time)) track.append(Message('note_off', note=int(note), velocity = 127, time=time)) track.append(Message('note_on', note=mutantnotelist2[len(mutantnotelist2)-1], velocity = 127, time=time)) track.append(Message('note_off', note=mutantnotelist2[len(mutantnotelist2)-1], velocity = 127, time=500)) mid.save('mutantmusic/' + filename + str(midino) + '.mid')
def merge_tracksFIXED(tracks): """Returns a MidiTrack object with all messages from all tracks. The messages are returned in playback order with delta times as if they were all in one track. """ now = 0 # REMOVE THIS messages = MidiTrack() for track in tracks: now = 0 # ADD THIS for message in track: now += message.time if message.type not in ('track_name', 'end_of_track'): messages.append(message.copy(time=now)) if message.type == 'end_of_track': break messages.sort(key=lambda x: x.time) messages.append(MetaMessage('end_of_track', time=now)) # Convert absolute time back to delta time. last_time = 0 for message in messages: message.time -= last_time last_time += message.time return messages
def time_warp(source_path, dest_path, ratio): # Read a midi file and return a dictionnary {track_name : pianoroll} mid_in = MidiFile(source_path) mid_out = MidiFile() # The two files need to have the same ticks per beat ticks_per_beat = mid_in.ticks_per_beat mid_out.ticks_per_beat = ticks_per_beat # Parse track by track for i, track_in in enumerate(mid_in.tracks): track_out = MidiTrack() mid_out.tracks.append(track_out) for message_in in track_in: time_in = message_in.time time_out = int(round(time_in * ratio)) # For absolutely every message, just mutliply the time by the ratio message_out = message_in.copy(time=time_out) track_out.append(message_out) mid_out.save(dest_path) return
def SaveVelocityDatatoMIDIFile(vData, fileName): with MidiFile(ticks_per_beat = 24) as mFile: track = MidiTrack() mFile.tracks.append(track) for n in MIDINotes: if (vData[0,n]>0): event = Message("note_on", velocity=int(vData[0,n]), note = int(n), time = int(0)) track.append(event) timeOfLastEvent = 0 for t in range(1,vData.shape[0]-1): for n in MIDINotes: if vData[t,n] != vData[t-1,n]: relativeTick = t - timeOfLastEvent timeOfLastEvent = t event = Message("note_on", velocity=int(vData[t,n]), note = int(n), time = int(relativeTick)) track.append(event) mFile.save(fileName) print("MIDI file was saved. Events: {} Length in ticks: {} Data dimensions: {}".format(len(track), timeOfLastEvent, vData.shape))
def toMidi(self, fname): with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) track.append(Message('program_change', program=12)) for note in self.getNotes(): for pitch in note.pitches: track.append(Message('note_on', note=pitch, velocity=100, time=0)) delta = note.duration for pitch in note.pitches: track.append(Message('note_off', note=pitch, velocity=100, time=delta)) delta = 0 outfile.save(fname)
def toMIDI(filename, ch, notes, rms, onset_start_times, onset_end_times, nOnsets): print 'Transcribing to MIDI in ' + filename delta = 0 with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) for i in range(nOnsets): stime = int((onset_start_times[i] - delta) * 1000) message = Message('note_on', note=int(notes[i]), velocity=int(rms[i] * 127), time=stime) message.channel = ch track.append(message) etime = int((onset_end_times[i] - delta) * 1000) off_message = Message('note_off', note=int(notes[i]), velocity=int(rms[i] * 127), time=etime) off_message.channel = ch track.append(off_message) delta = onset_end_times[i] outfile.print_tracks() outfile.save('/media/sf_VMshare/' + filename) print 'Transcription successfull!'
def createMidiFromPianoRoll(piano_roll, lowest_note, directory, mel_test_file, threshold, res_factor=1): ticks_per_beat = int(96/res_factor) mid = MidiFile(type=0, ticks_per_beat=ticks_per_beat) track = MidiTrack() mid.tracks.append(track) mid_files = [] delta_times = [0] for k in range(piano_roll.shape[1]):#initial starting values if piano_roll[0, k] == 1: track.append(Message('note_on', note=k+lowest_note, velocity=100, time=0)) delta_times.append(0) for j in range(piano_roll.shape[0]-1):#all values between first and last one set_note = 0 #Check, if for the current timestep a note has already been changed (set to note_on or note_off) for k in range(piano_roll.shape[1]): if (piano_roll[j+1, k] == 1 and piano_roll[j, k] == 0) or (piano_roll[j+1, k] == 0 and piano_roll[j, k] == 1):#only do something if note_on or note_off are to be set if set_note == 0: time = j+1 - sum(delta_times) delta_times.append(time) else: time = 0 if piano_roll[j+1, k] == 1 and piano_roll[j, k] == 0: set_note += 1 track.append(Message('note_on', note=k+lowest_note, velocity=100, time=time)) if piano_roll[j+1, k] == 0 and piano_roll[j, k] == 1: set_note += 1 track.append(Message('note_off', note=k+lowest_note, velocity=64, time=time)) mid.save('%s%s_th%s.mid' %(directory, mel_test_file, threshold)) mid_files.append('%s.mid' %(mel_test_file)) return
#!/usr/bin/env python """ Create a new MIDI file with some random notes. The file is saved to test.mid. """ from __future__ import division import random import sys from mido import Message, MidiFile, MidiTrack, MAX_PITCHWHEEL notes = [64, 64+7, 64+12] outfile = MidiFile() track = MidiTrack() outfile.tracks.append(track) track.append(Message('program_change', program=12)) delta = 300 ticks_per_expr = int(sys.argv[1]) if len(sys.argv) > 1 else 20 for i in range(4): note = random.choice(notes) track.append(Message('note_on', note=note, velocity=100, time=delta)) for j in range(delta // ticks_per_expr): pitch = MAX_PITCHWHEEL * j * ticks_per_expr // delta track.append(Message('pitchwheel', pitch=pitch, time=ticks_per_expr)) track.append(Message('note_off', note=note, velocity=100, time=0)) outfile.save('test.mid')
def quantize_track(track, ticks_per_quarter, quantization): '''Return the differential time stamps of the note_on, note_off, and end_of_track events, in order of appearance, with the note_on events quantized to the grid given by the quantization. Arguments: track -- MIDI track containing note event and other messages ticks_per_quarter -- The number of ticks per quarter note quantization -- The note duration, represented as 1/2**quantization.''' pp = pprint.PrettyPrinter() # Message timestamps are represented as differences between # consecutive events. Annotate messages with cumulative timestamps. # Assume the following structure: # [header meta messages] [note messages] [end_of_track message] first_note_msg_idx = None for i, msg in enumerate(track): if msg.type == 'note_on': first_note_msg_idx = i break cum_msgs = zip( np.cumsum([msg.time for msg in track[first_note_msg_idx:]]), [msg for msg in track[first_note_msg_idx:]]) end_of_track_cum_time = cum_msgs[-1][0] quantized_track = MidiTrack() quantized_track.extend(track[:first_note_msg_idx]) # Keep track of note_on events that have not had an off event yet. # note number -> message open_msgs = defaultdict(list) quantized_msgs = [] for cum_time, msg in cum_msgs: if DEBUG: print msg pp.pprint(open_msgs) if msg.type == 'note_on' and msg.velocity > 0: # Store until note off event. Note that there can be # several note events for the same note. Subsequent # note_off events will be associated with these note_on # events in FIFO fashion. open_msgs[msg.note].append((cum_time, msg)) elif msg.type == 'note_off' or (msg.type == 'note_on' and msg.velocity == 0): assert msg.note in open_msgs, \ 'Bad MIDI. Cannot have note off event before note on event' note_on_open_msgs = open_msgs[msg.note] note_on_cum_time, note_on_msg = note_on_open_msgs[0] open_msgs[msg.note] = note_on_open_msgs[1:] # Quantized note_on time quantized_note_on_cum_time = quantize_tick( note_on_cum_time, ticks_per_quarter, quantization) # The cumulative time of note_off is the quantized # cumulative time of note_on plus the orginal difference # of the unquantized cumulative times. quantized_note_off_cum_time = quantized_note_on_cum_time + (cum_time - note_on_cum_time) quantized_msgs.append((min(end_of_track_cum_time, quantized_note_on_cum_time), note_on_msg)) quantized_msgs.append((min(end_of_track_cum_time, quantized_note_off_cum_time), msg)) elif msg.type == 'end_of_track': quantized_msgs.append((cum_time, msg)) # Now, sort the quantized messages by (cumulative time, # note_type), making sure that note_on events come before note_off # events when two event have the same cumulative time. Compute # differential times and construct the quantized track messages. quantized_msgs.sort( key=lambda (cum_time, msg): cum_time if (msg.type=='note_on' and msg.velocity > 0) else cum_time + 0.5) diff_times = [0] + list( np.diff([ msg[0] for msg in quantized_msgs ])) for diff_time, (cum_time, msg) in zip(diff_times, quantized_msgs): quantized_track.append(msg.copy(time=diff_time)) if DEBUG: pp.pprint(quantized_msgs) pp.pprint(diff_times) return quantized_track
def array_to_midi(array, name, quantization=5, pitch_offset=0, midi_type=1, ticks_per_quarter=240): '''Convert an array into a MIDI object. When an MIDI object is converted to an array, information is lost. That information needs to be provided to create a new MIDI object from the array. For this application, we don't care about this metadata, so we'll use some default values. Arguments: array -- An array A[time_step, note_number] = 1 if note on, 0 otherwise. quantization -- The note duration, represented as 1/2**quantization. pitch_offset -- Offset the pitch number relative to the array index. midi_type -- Type of MIDI format. ticks_per_quarter -- The number of MIDI timesteps per quarter note.''' mid = MidiFile() meta_track = MidiTrack() note_track = MidiTrack() mid.tracks.append(meta_track) mid.tracks.append(note_track) meta_track.append(MetaMessage('track_name', name=name, time=0)) meta_track.append(MetaMessage('time_signature', numerator=4, denominator=4, clocks_per_click=24, notated_32nd_notes_per_beat=8, time=0)) meta_track.append(MetaMessage('set_tempo', tempo=500000, time=0)) meta_track.append(MetaMessage('end_of_track', time=0)) ticks_per_quantum = ticks_per_quarter * 4 / 2**quantization note_track.append(MetaMessage('track_name', name=name, time=0)) cumulative_events = [] for t, time_slice in enumerate(array): for i, pitch_on in enumerate(time_slice): if pitch_on > 0: cumulative_events.append(dict( type = 'note_on', pitch = i + pitch_offset, time = ticks_per_quantum * t )) cumulative_events.append(dict( type = 'note_off', pitch = i + pitch_offset, time = ticks_per_quantum * (t+1) )) cumulative_events.sort( key=lambda msg: msg['time'] if msg['type']=='note_on' else msg['time'] + 0.5) last_time = 0 for msg in cumulative_events: note_track.append(Message(type=msg['type'], channel=9, note=msg['pitch'], velocity=100, time=msg['time']-last_time)) last_time = msg['time'] note_track.append(MetaMessage('end_of_track', time=0)) return mid
import ROOT tb = ROOT.TBrowser() f = ROOT.TFile("/afs/cern.ch/user/y/yijiang/SA_test_ttH_ttHemjets10.root") t = f.Get("METree") for event in t: n1= event.ME_Sig_Max_Likelihoods import mido from mido import Message, MidiFile, MidiTrack with MidiFile() as mid: track = MidiTrack() mid.tracks.append(track) track.append(mido.Message('program_change', program=12, time=0)) for val in n1 : track.append(mido.Message('note_on', note=int(val), velocity=64, time=100)) track.append(mido.Message('note_off', note=int(val), velocity=127, time=100)) mid.save('/afs/cern.ch/user/y/yijiang/new_song.mid')
#!/usr/bin/env python import mido from mido import Message, MidiFile, MidiTrack import time tracks = [] with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) # track.append(Message('program_change', program=12, time=0)) track.append(Message("note_on", note=64, velocity=64, time=0)) track.append(Message("note_off", note=64, velocity=127, time=1000)) outfile.save("new_song.mid")
#!/usr/bin/env python """ Create a new MIDI file with some random notes. The file is saved to test.mid. """ import random from mido import Message, MidiFile, MidiTrack notes = [64, 64+7, 64+12] with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) track.append(Message('program_change', program=12)) delta = 16 for i in range(4): note = random.choice(notes) track.append(Message('note_on', note=note, velocity=100, time=delta)) track.append(Message('note_off', note=note, velocity=100, time=delta)) outfile.save('test.mid')
def array_to_MIDI(array,sig_length): # get relative times between events test_times = (np.diff(np.sort(np.concatenate((array[:,1],array[:,2])))* 512./44100)).astype(float) test_duration = (np.diff(np.sort(np.concatenate((array[:,1],array[:,2])))* 512./44100*960)).astype(int) #print array #print test_duration #print test_times #* 512./44100*960) # write MIDI file with MidiFile() as outfile: # Initialize track = MidiTrack() outfile.tracks.append(track) # add MIDI events track.append(Message('program_change', program=12)) seg_skip_on = 1 # take segments and make midi note events for segment in xrange(0,array.shape[0]): if segment == 0: track.append(Message('note_on', note=array[0,0], velocity=array[0,3], time=int(array[0,1]*512./44100*960))) track.append(Message('note_off', note=array[0,0], velocity=array[0,3], time=test_duration[0])) else: track.append(Message('note_on', note=array[segment,0], velocity=array[segment,3], time=test_duration[seg_skip_on])) seg_skip_off = seg_skip_on + 1 track.append(Message('note_off', note=array[segment,0], velocity=array[segment,3], time=test_duration[seg_skip_off])) #print test_duration[seg_skip_off] seg_skip_on = seg_skip_off + 1 track_end = int((sig_length/44100. - 512./44100 * array[-1,2])*960) track.append(Message('program_change', program=12, time=track_end)) track.append(MetaMessage('end_of_track')) #outfile.save('output.mid') # output MIDI file return outfile
from mido import Message, MetaMessage, MidiFile, MidiTrack # MIDI test objects # Track that is already quantized. track0 = MidiTrack() track0.append(MetaMessage('track_name', name='test0', time=0)) track0.append(Message('note_on', note=60, velocity=64, time=0)) track0.append(Message('note_off', note=60, velocity=64, time=50)) track0.append(MetaMessage('end_of_track', time=0)) # Simple track that is not quantized. track1 = MidiTrack() track1.append(MetaMessage('track_name', name='test1', time=0)) track1.append(Message('note_on', note=60, velocity=64, time=2)) track1.append(Message('note_off', note=60, velocity=64, time=50)) track1.append(MetaMessage('end_of_track', time=0)) # Track with notes that, when quantized to 32nd notes, would run over # the original end time of the track. track2 = MidiTrack() track2.append(MetaMessage('track_name', name='test2', time=0)) track2.append(Message('note_on', note=60, velocity=64, time=29)) track2.append(Message('note_off', note=60, velocity=64, time=31)) track2.append(MetaMessage('end_of_track', time=0)) meta_track = MidiTrack() meta_track.append(MetaMessage('track_name', name='meta-track', time=0)) midi_notes_in_track0 = MidiFile() midi_notes_in_track0.tracks.append(track0)
win_s = 512 // downsample # fft size hop_s = 256 // downsample # hop size s = source(filename, samplerate, hop_s) samplerate = s.samplerate tolerance = 0.8 notes_o = notes("default", win_s, hop_s, samplerate) print("%8s" % "time","[ start","vel","last ]") # create a midi file mid = MidiFile() track = MidiTrack() mid.tracks.append(track) ticks_per_beat = mid.ticks_per_beat # default: 480 bpm = 120 # default midi tempo tempo = bpm2tempo(bpm) track.append(MetaMessage('set_tempo', tempo=tempo)) track.append(MetaMessage('time_signature', numerator=4, denominator=4)) def frames2tick(frames, samplerate=samplerate): sec = frames / float(samplerate) return int(second2tick(sec, ticks_per_beat, tempo)) last_time = 0
def generate_random(snote=50, mlength=12, numofmidi=10, time=150, filename='random', pitchrnd=False): notes = range(snote, snote+mlength) noterange = range(mlength) # pitch range for random pitch value ; pitches = range(-8192,8191) # Create music folder if it does not exist if not os.path.exists('music'): os.makedirs('music') for j in range(numofmidi): mid = MidiFile(type=0) # type0 can have only one track track = MidiTrack() # note list (kind of) mid.tracks.append(track) # the note which the pitch will change for pitchnote = random.choice(noterange) numofpnote = random.choice(noterange) for i in noterange: note = random.choice(notes) pitch = random.choice(pitches) if pitchrnd: if i == pitchnote: # Change the pitch on the note track.append(Message('pitchwheel', pitch=pitch)) if i == (pitchnote+numofpnote): # Change the pitch back to default track.append(Message('pitchwheel')) track.append(Message('note_on', note=note, velocity = 127, time=time)) track.append(Message('note_off', note=note, velocity = 127, time=time)) note = random.choice(notes) track.append(Message('note_on', note=note, velocity = 127, time=time)) track.append(Message('note_off', note=note, velocity = 127, time=500)) mid.save('music/' + filename + str(j) + '.mid')
for pred in prediction: for i in range(0,4): pred[i] = pred[i] * (max_val[i]-min_val[i]) + min_val[i] if pred[i] < min_val[i]: pred[i] = min_val[i] if pred[i] >= max_val[i]: pred[i] = max_val[i] ########################################### ###### SAVING TRACK FROM BYTES DATA ####### mid = MidiFile() track = MidiTrack() mid.tracks.append(track) for note in prediction: # 147 means note_on note = np.insert(note, 1, 144) bytes = np.round(note).astype(int) msg = Message.from_bytes(bytes[1:4]) msg.time = int(note[4]/0.00125) # to rescale to midi's delta ticks. arbitrary value for now. msg.channel = bytes[0] print(msg) track.append(msg) mid.save('new_song.mid')
from mido import MidiFile, MidiTrack, Message import random mid = MidiFile(type=0) track = MidiTrack() mid.tracks.append(track) notes = range(40, 90) for i in range(20): note = random.choice(notes) track.append(Message('note_on', note=note, velocity=100, time=i*100)) track.append(Message('note_off', note=note, velocity=100, time=(i+1)*100)) mid.save('random.mid')