def main(): mid = MidiFile('midi/Untitled_2044026_1.mid') for i, track in enumerate(mid.tracks): print('Track {}: {}'.format(i, track.name)) for msg in track: print(msg) print("Select chord progression:") print("1. I V vi IV") print("2. i bVII VI V") choice = int(input()) if choice==1: mid = MidiFile() track0 = MidiTrack() mid.tracks.append(track0) track0.append(MetaMessage('time_signature', numerator=4, denominator=4, clocks_per_click=24, notated_32nd_notes_per_beat=8, time=0)) track0.append(MetaMessage('set_tempo', tempo = 833333, time=0)) track0.append(MetaMessage('end_of_track', time=0)) track1 = MidiTrack() mid.tracks.append(track1) track1.append(MetaMessage('track_name', name='Smooth Synth', time=0)) track1.append(Message('program_change', channel=0, program=80, time=0)) track1.append(Message('note_on', channel=0, note=60, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=64, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=67, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=67, velocity = 50, time=768)) track1.append(Message('note_off', channel=0, note=64, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=60, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=67, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=62, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=59, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=67, velocity = 50, time=768)) track1.append(Message('note_off', channel=0, note=62, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=59, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=57, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=60, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=64, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=57, velocity = 50, time=768)) track1.append(Message('note_off', channel=0, note=60, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=64, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=60, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=65, velocity = 50, time=0)) track1.append(Message('note_on', channel=0, note=57, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=60, velocity = 50, time=768)) track1.append(Message('note_off', channel=0, note=65, velocity = 50, time=0)) track1.append(Message('note_off', channel=0, note=57, velocity = 50, time=0)) track1.append(MetaMessage('end_of_track', time=0)) mid.save('midi/new_song.mid') else: print("Not finished yet.")
def Initialize_Track(Instrument=1, Tempo=714280, Key='C'): Track = MidiTrack() Track.append(MetaMessage("track_name", name='Musicine', time=0)) Track.append(MetaMessage('key_signature', key=Key, time=0)) Track.append(Message('program_change', channel=0, program=Instrument, time=0)) # change the type of instrument Track.append(MetaMessage("set_tempo", tempo=Tempo, time=0)) return Track
def save_musical_file(path: str, out: str = None): if out is None: out = path f = MidiFile() ap = f.add_track('Main').append last_bpm = tempo2bpm(DEFAULT_TEMPO) ap(MetaMessage("set_tempo", tempo=DEFAULT_TEMPO)) notes_on = [] i = 0 for bpm, duration, notes in musical_extract_midi(path): i += 1 if notes_on: ap(Message(type='note_off', note=notes_on[0], time=int(duration * f.ticks_per_beat * 0.95))) for n in notes_on[1:]: ap(Message(type='note_off', note=n, time=0)) notes_on = notes ap(Message(type='note_on', note=notes_on[0], time=int(duration * f.ticks_per_beat * 0.05))) for n in notes_on: ap(Message(type='note_on', note=n, time=0)) if bpm != last_bpm: last_bpm = bpm ap(MetaMessage("set_tempo", tempo=bpm2tempo(bpm))) if notes_on: # Last note; just make it 1 beat long ap(Message(type='note_off', note=notes_on[0], time=f.ticks_per_beat)) for n in notes_on[1:]: ap(Message(type='note_off', note=n, time=0)) f.save(out) print(f"{i} hits wrote to {out}")
def matrix_to_mid(matrix, output_file=None, ticks_per_beat=96, vel=100): mid = MidiFile() mid.ticks_per_beat = ticks_per_beat mid.type = 0 track = MidiTrack() mid.tracks.append(track) if output_file is not None: track.append(MetaMessage("track_name", name=os.path.split(output_file)[1], time=int(0))) track.append(MetaMessage("set_tempo", tempo=480000, time=int(0))) track.append(MetaMessage("time_signature", numerator=4, denominator=4, time=int(0))) sort_events = [] for row in matrix: sort_events.append([row[0], 1, row[1]]) sort_events.append([row[0], 0, (row[1] + row[2])]) sort_events.sort(key=lambda tup: tup[2]) lapso = 0 for evt in sort_events: if evt[1] == 1: track.append(Message('note_on', note=evt[0], velocity=vel, time=int((evt[2] - lapso) * ticks_per_beat))) lapso = evt[2] elif evt[1] == 0: track.append(Message('note_off', note=evt[0], velocity=0, time=int((evt[2] - lapso) * ticks_per_beat))) lapso = evt[2] if output_file is not None: track.append(MetaMessage('end_of_track', time=(int(0)))) mid.save(output_file) return mid
def to_mido_meta_track(music: "Music") -> MidiTrack: """Return a mido MidiTrack containing metadata of a Music object. Parameters ---------- music : :class:`muspy.Music` object Music object to convert. Returns ------- :class:`mido.MidiTrack` object Converted mido MidiTrack object. """ # Create a track to store the metadata meta_track = MidiTrack() # Song title if music.metadata.title is not None: meta_track.append(MetaMessage("track_name", name=music.metadata.title)) # Tempos for tempo in music.tempos: meta_track.append(to_mido_tempo(tempo)) # Key signatures for key_signature in music.key_signatures: mido_key_signature = to_mido_key_signature(key_signature) if mido_key_signature is not None: meta_track.append(mido_key_signature) # Time signatures for time_signature in music.time_signatures: meta_track.append(to_mido_time_signature(time_signature)) # Lyrics for lyric in music.lyrics: meta_track.append(to_mido_lyric(lyric)) # Annotations for annotation in music.annotations: # Marker messages if annotation.group == "marker": meta_track.append(MetaMessage("marker", text=annotation.annotation)) # Text messages elif isinstance(annotation.annotation, str): meta_track.append( MetaMessage("text", time=annotation.time, text=annotation.annotation)) # End of track message meta_track.append(MetaMessage("end_of_track")) # Convert to delta time to_delta_time(meta_track) return meta_track
def add_meta_info(self): tempo = mido.bpm2tempo(self.bpm) numerator = Fraction(self.time_signature).numerator denominator = Fraction(self.time_signature).denominator super().append(MetaMessage('time_signature', numerator=numerator, denominator=denominator)) super().append(MetaMessage('set_tempo', tempo=tempo, time=0)) super().append(MetaMessage('key_signature', key=self.key)) for channel, program in self.instruments.items(): super().append(Message('program_change', channel=int(channel), program=program, time=0))
def to_mido_track( track: Track, channel: Optional[int] = None, use_note_off_message: bool = False, ) -> MidiTrack: """Return a Track object as a mido MidiTrack object. Parameters ---------- track : :class:`muspy.Track` object Track object to convert. use_note_off_message : bool, optional Whether to use note-off messages. If False, note-on messages with zero velocity are used instead. The advantage to using note-on messages at zero velocity is that it can avoid sending additional status bytes when Running Status is employed. Defaults to False. channel : int, optional Channel number. Defaults to 10 for drums and 0 for other instruments. Returns ------- :class:`mido.MidiTrack` object Converted mido MidiTrack object. """ if channel is None: channel = 9 if track.is_drum else 0 # Create a new MIDI track midi_track = MidiTrack() # Track name messages if track.name is not None: midi_track.append(MetaMessage("track_name", name=track.name)) # Program change messages midi_track.append( Message("program_change", program=track.program, channel=channel)) # Note on and note off messages for note in track.notes: midi_track.extend( to_mido_note_on_note_off( note, channel=channel, use_note_off_message=use_note_off_message, )) # End of track message midi_track.append(MetaMessage("end_of_track")) # Convert to delta time to_delta_time(midi_track) return midi_track
def audio_to_midi(filename, midioutput, samplerate=44100, downsample=1): samplerate = 44100 // downsample win_s = 512 // downsample # fft size hop_s = 128 // 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 # total number of frames read total_frames = 0 while True: samples, read = s() new_note = notes_o(samples) if (new_note[0] != 0): note_str = ' '.join(["%.2f" % i for i in new_note]) print("%.6f" % (total_frames/float(samplerate)), new_note) delta = frames2tick(total_frames) - last_time if new_note[2] > 0: track.append(Message('note_off', note=int(new_note[2]), velocity=127, time=delta) ) track.append(Message('note_on', note=int(new_note[0]), velocity=int(new_note[1]), time=delta) ) last_time = frames2tick(total_frames) total_frames += read if read < hop_s: break mid.save(midioutput)
def convert_txt_to_midi(progression): mid = MidiFile() txt_file = open("midi/" + progression + ".txt", "r") lines = txt_file.readlines() track = "" for line in lines: if (line[0:5] == "Track"): track = MidiTrack() mid.tracks.append(track) elif ("meta" in line): if ("time_signature" in line): params = extract_int(line) track.append( MetaMessage('time_signature', numerator=params[0], denominator=params[1], clocks_per_click=params[2], notated_32nd_notes_per_beat=params[4], time=params[5])) elif ("set_tempo" in line): params = extract_int(line) track.append( MetaMessage('set_tempo', tempo=params[0], time=params[1])) elif ("track_name" in line): names = line.split("'") params = extract_int(line) track.append( MetaMessage("track_name", name=names[1], time=params[0])) else: params = extract_int(line) track.append(MetaMessage('end_of_track', time=params[0])) elif ("program_change" in line): params = extract_int(line) track.append( Message('program_change', channel=params[0], program=params[1], time=params[2])) elif ("note_on" in line): params = extract_int(line) track.append( Message("note_on", channel=params[0], note=params[1], velocity=params[2], time=params[3])) elif ("note_off" in line): params = extract_int(line) track.append( Message("note_off", channel=params[0], note=params[1], velocity=params[2], time=params[3])) mid.save("midi/" + progression + ".mid")
def df_to_mid(df, label_part, index='s', bpm=60, ppq=1000, program=22) -> MidiTrack: track = MidiTrack() track.append(Message('program_change', program=program, time=0)) track.append(MetaMessage('time_signature', time=0)) track.append(MetaMessage('set_tempo', tempo=bpm2tempo(bpm), time=0)) index_seconds = df.index.get_level_values(1) time_s_last = list(index_seconds)[0] df.loc[(slice(None), index_seconds[1:]), :]['chord'].tolist() df.loc[(slice(None), index_seconds[1:]), :]['chord'].tolist() for time_s in list(index_seconds): diff_ticks_last_event = s_to_ticks(time_s, bpm=bpm, ppq=ppq) - s_to_ticks( time_s_last, bpm=bpm, ppq=ppq) for i_note, note in enumerate(df.loc[(slice(None), time_s_last), 'chord'].tolist()[0]): if i_note == 0: track.append( Message('note_off', note=note.pitch, velocity=note.velocity, time=diff_ticks_last_event)) else: track.append( Message('note_off', note=note.pitch, velocity=note.velocity, time=0)) for i_note, note in enumerate(df.loc[(slice(None), time_s), 'chord'].tolist()[0]): track.append( Message('note_on', note=note.pitch, velocity=note.velocity, time=0)) time_s_last = time_s return track
def tempo(beats, trk=None, bt=480): """Create a track setting a tempo at each new beat""" if not trk: trk = MidiTrack() trk.name = "Tempo variation" trk.append(MetaMessage("set_tempo", tempo=beats[0], time=0)) for i, beat in enumerate(beats): trk.append(MetaMessage("set_tempo", time=bt, tempo=beat)) return trk
def __init__(self, bpm=90, numerator=4, denominator=4): self.tempo = mido.bpm2tempo(bpm) # time_signature表示曲风 # numerator表示节拍,denominator表示小节 # numerator/denominator = 4/4 self.meta_time = MetaMessage('time_signature', numerator=numerator, denominator=denominator) self.meta_tempo = MetaMessage('set_tempo', tempo=self.tempo, time=0) self.meta_tone = MetaMessage('key_signature', key='C')
def outmidi(file): # build a midi file and set the header mid = MidiFile() track = MidiTrack() mid.tracks.append(track) track.append(MetaMessage('key_signature', key='C')) track.append(MetaMessage('instrument_name', name="Steel Drums")) track.append(MetaMessage('channel_prefix', channel=10)) track.append(Message('program_change', program=0, time=0)) array = [] # all the data in csv with open(filepathin + "\\\\" + file, 'r') as inp: for row in csv.reader(inp): row[0] = int(row[0]) row[1] = int(row[1]) array.append(row) rest = [] #all the tempo note = [] # all the note for ro in array: if ro[1] < 128: note.append(ro) i = ro[0] + 100 # tick + 100 j = ro[1] + 100 # pitch + 100 means note off note.append([i, j]) else: rest.append(ro) for row in rest: note.append(row) seq = sorted(note, key=(lambda x: x[0])) #all the data after sort time0 = 0 for row in seq: tim = row[0] - time0 time0 = row[0] if row[1] > 128 and row[1] < 228: # note off track.append( Message('note_off', note=row[1] - 100, velocity=64, time=tim)) elif row[1] < 128: #note on track.append(Message('note_on', note=row[1], velocity=64, time=tim)) elif row[1] > 10000: # tempo track.append(MetaMessage('set_tempo', tempo=row[1], time=tim)) else: down = row[1] % 100 up = int((row[1] - down) / 300) track.append( MetaMessage('time_signature', numerator=up, denominator=down)) mid.save(pathout + '\\\\' + file + '.mid')
def outputMidi(output_dir, piano_roll, tempo=120, resolution=480, scale=1, velocity=65): ''' convert the piano roll to midi file params: output_dir: the directory to store output file piano_roll: a list of (N = #files) matrices of size (timestep x pitch_dimension) tempo: default: 120 the tempo value from midi file resolution: default: 480 the resolution value from midi file scale: default:1 the number of ticks per time slice. for best performance: = length of sequence in one prediction velocity: default:65 the speed/strength to play a note ''' ticks_per_time = (resolution * tempo * unit_time) / 60.0 mid = MidiFile(ticks_per_beat=int(resolution)) track = MidiTrack() track.append(MetaMessage('set_tempo', tempo=int(60000000 / tempo), time=0)) note_events = ["note_off", "note_on"] last_state = np.zeros(pitch_dimension) last_index = 0 for current_index, current_state in enumerate( np.concatenate((piano_roll, last_state.reshape(1, -1)), axis=0)): # terminate note at the end delta = current_state - last_state last_state = current_state for i in range(len(delta)): if delta[i] == 1 or delta[i] == -1: # play/stop note event = Message(note_events[delta[i] > 0], time=int(scale * (current_index - last_index) * ticks_per_time), velocity=velocity, note=(lowest_note + i)) track.append(event) last_index = current_index else: pass # don't change note state end = MetaMessage('end_of_track', time=1) track.append(end) mid.tracks.append(track) mid.save(output_dir)
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
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 to_midi_file(self) -> MidiFile: midi_file = MidiFile() track_meta = MidiTrack() track_meta.append(MetaMessage("time_signature", numerator=self.numerator, denominator=self.denominator)) track_right = self.right_hand.to_midi_track() track_right.insert(0, MetaMessage("track_name", name="Right Hand\x00", time=0)) track_left = self.left_hand.to_midi_track() track_left.insert(0, MetaMessage("track_name", name="Left Hand\x00", time=0)) midi_file.tracks.append(track_meta) midi_file.tracks.append(track_right) midi_file.tracks.append(track_left) return midi_file
def _write_track_header(self, track: MidiTrack, channel: int = 0, track_name: str = "Midi Track"): track.append(MetaMessage("channel_prefix", channel=channel, time=0)) track.append(MetaMessage("track_name", name=track_name, time=0)) track.append( MetaMessage("smpte_offset", frame_rate=24, hours=32, minutes=0, seconds=0, frames=0, sub_frames=0, time=0))
def make_training_audio(channel, program, note_list, duration, sr): with tempfile.TemporaryDirectory() as tmp_dir: midi_path = os.path.join(tmp_dir, 'train.mid') wave_path = os.path.join(tmp_dir, 'train.wav') fnull = open(os.devnull, 'w') mid = MidiFile() track = MidiTrack() mid.tracks.append(track) track.append(MetaMessage('set_tempo', tempo=bpm2tempo(240))) track.append( Message('program_change', channel=channel - 1, program=program - 1, time=0)) for ni, note in enumerate(note_list): track.append( Message('note_on', note=note, time=int(1000 * duration) if ni > 0 else 0)) track.append( Message('note_off', note=note, time=int(1000 * duration))) mid.save(midi_path) subprocess.call(['musescore', '-o', wave_path, midi_path], stdout=fnull, stderr=fnull) y, _ = librosa.core.load(wave_path, sr, duration=(len(note_list) + 1) * duration) return y
def write_song(self, file_name): mid = MidiFile(type=1) # 0 type means all messages are on one track track_pitch = [0, -12] track_num = 2 tracks = [] for i in range(track_num): track = MidiTrack() tracks.append(track) mid.tracks.append(track) track.append( MetaMessage("set_tempo", tempo=mido.bpm2tempo(self.bpm))) for i, note in enumerate(self.notes): tracks[i % track_num].append( Message("note_on", note=note.pitch + track_pitch[i % track_num], velocity=127, time=0)) tracks[i % track_num].append( Message("note_on", note=note.pitch + track_pitch[i % track_num], velocity=0, time=note.duration * mid.ticks_per_beat)) mid.save(file_name)
def write_output_file(output_midi_data, output_fullname, msg_count, transpose_offset): filename_with_ext = os.path.basename(output_fullname) filename_without_ext, ext = os.path.splitext(filename_with_ext) log(INFO, 'Writing output: {}'.format(filename_without_ext)) # If necessary, truncate last (out of range) messages in the single track we created del output_midi_data.tracks[0][msg_count:] # Add an End of track message, some little time after the very last note # (needed to hear this last note being played, while previewing on a local PC) output_midi_data.tracks[0].append(MetaMessage('end_of_track', time=100)) # If necessary, transpose all notes in the single track we created if transpose_offset != 0: for msg in output_midi_data.tracks[0]: if msg.type in ['note_on']: msg.note += transpose_offset # Actually save file output_midi_data.save(output_fullname) return
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 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 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_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 generateRandomMidi(filename, dsconfig): nbbeats = 10 #notes = np.arange(nbnotes) + 80 mid = MidiFile() track = MidiTrack() mid.tracks.append(track) mid.ticks_per_beat = 32 #74 is flute #0 is piano instrument = np.random.choice(dsconfig["instruments"]) track.append(Message('program_change', program=instrument, time=0)) track.append(MetaMessage('set_tempo', tempo=1000000, time=0)) maxduration = nbbeats * mid.ticks_per_beat endtime = 0 while endtime < maxduration: note = np.random.randint(40, 100) velocity = np.random.randint(70, 127) curendtime = endtime duration = np.random.randint(6, 50) endtime = endtime + duration endtime = min(endtime, maxduration) duration = endtime - curendtime #we sometimes add silences if (np.random.rand() > 0.9): velocity = 0 track.append(Message('note_on', note=note, velocity=velocity, time=0)) track.append( Message('note_off', note=note, velocity=127, time=duration)) pianoroll = eventSequenceToPianoRoll(mid.ticks_per_beat, track) mid.save(filename) return pianoroll
def save_processed_file(path: str, out: str = None, resolution=1 / 16): if out is None: out = path f = MidiFile(ticks_per_beat=1) ap = f.add_track('Main').append ap(MetaMessage("set_tempo", tempo=100000)) def on(note: int, time: int): ap(Message(type='note_on', note=note, time=time)) def off(note: int, time: int): ap(Message(type='note_off', note=note, time=time)) def note(time: int, *notes): if notes: for n in notes: on(n, 0) off(notes[0], time) for n in notes[1:]: off(n, 0) i = 0 for fwd, notes in readAndProcessMidi(path, resolution): note(fwd, *notes) i += 1 f.save(out) print(f"{i} hits wrote to {out}")
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 jnn_track_to_midi_track(jnn_track, jnn_instrument, channel): # TODO: TORCH messages = [ Message(type='program_change', channel=channel, program=JNN_INSTRUMENTS[jnn_instrument], time=0), MetaMessage("track_name", name=jnn_instrument, time=0) ] for jnn_note in jnn_track: note, start, duration = jnn_note messages.append( Message(type="note_on", channel=channel, note=note, velocity=50, time=start)) messages.append( Message(type="note_off", channel=channel, note=note, velocity=0, time=start + duration)) messages.sort(key=lambda msg: msg.time) return MidiTrack(mitracks.fix_end_of_track(mitracks._to_reltime(messages)))
def to_mido_lyric(lyric: Lyric) -> MetaMessage: """Return a Lyric object as a mido MetaMessage object. Timing is in absolute time, NOT in delta time. """ return MetaMessage("lyrics", time=lyric.time, text=lyric.lyric)