def convert(arr, name): mid = mido.MidiFile() mid.ticks_per_beat = 960 track = mido.MidiTrack() mid.tracks.append(track) track.append(mido.MetaMessage("time_signature", numerator=4, denominator=4)) track.append(mido.MetaMessage("set_tempo", tempo = 600000)) i = 0 first = 1 for el in arr: #print(el) if el[0] == 1: track.append(npy2msg(el)) mid.save('songs/'+name+str(i)+'.mid') i += 1 first = 1 elif first == 1: first = 0 mid = mido.MidiFile() mid.ticks_per_beat = 960 track = mido.MidiTrack() mid.tracks.append(track) track.append(mido.MetaMessage("time_signature", numerator=4, denominator=4)) track.append(mido.MetaMessage("set_tempo", tempo = 600000)) track.append(npy2msg(el)) else: track.append(npy2msg(el)) mid.save('songs/'+name+str(i)+'.mid')
def write_midi(filename, notes, tpb): mid = mido.MidiFile( ticks_per_beat=tpb ) # copy ticks_per_beat from source to avoid rounding errors track = mido.MidiTrack() mid.tracks.append(track) tempo = mido.bpm2tempo(120) track.append(mido.MetaMessage('set_tempo', tempo=tempo)) track.append(mido.MetaMessage('time_signature')) track.append(mido.Message('program_change', program=0)) events = [(n[0], n[1], 'note_on') for n in notes] events.extend([(n[0], n[2], 'note_off') for n in notes]) events = sorted(events, key=lambda n: n[1]) time = t0 = 0 for pitch, t1, eventtype in events: time += t1 - t0 dt = mido.second2tick(t1 - t0, tpb, tempo) message = mido.Message(eventtype, note=pitch, velocity=64, time=round(dt)) track.append(message) t0 = t1 mid.save(filename)
def reconversion(list_track_one, filepath): ''' reconversing codes to midi file ''' mid = mido.MidiFile() track = mido.MidiTrack() mid.tracks.append(track) print("\n----Making Midi File----\n") print("Ticks per beat:{}\n".format(mid.ticks_per_beat)) track.append(mido.MetaMessage('set_tempo', tempo=500000, time=0)) track.append(mido.MetaMessage('track_name', name='Piano', time=0)) track.append(mido.Message('program_change', program=0, time=0)) for i in range(len(list_track_one)): track.append( mido.Message('note_on', note=list_track_one[i][1], velocity=list_track_one[i][2], time=50)) track.append( mido.Message('note_off', note=list_track_one[i][1], velocity=list_track_one[i][1], time=list_track_one[i][0])) mid.save(filepath)
def to_midi_from_matrix(self, matrix): """ matrix representation into midi file """ matrix_prev = [[0 for _ in range(self.span)]] + matrix[:-1] pattern = mido.MidiFile() pattern.ticks_per_beat = 16 track = mido.MidiTrack() pattern.tracks.append(track) track.append( mido.MetaMessage('set_tempo', tempo=mido.bpm2tempo(120), time=0)) last_event_tick = 0 for tick, (state, previous_state) in enumerate(zip(matrix, matrix_prev)): offNotes, onNotes = [], [] for pitch, (n, p) in enumerate(zip(state, previous_state)): if p == 1 and n == 0: self.add_note_off_event(track, tick - last_event_tick, pitch + self.lowerbound) last_event_tick = tick elif p == 0 and n == 1: self.add_note_on_event(track, tick - last_event_tick, pitch + self.lowerbound) last_event_tick = tick if tick == len(matrix) - 1 and n == 1: self.add_note_off_event(track, tick - last_event_tick, pitch + self.lowerbound) last_event_tick = tick track.append(mido.MetaMessage('end_of_track', time=last_event_tick + 1)) return pattern
def to_midi_track(self, use_hanzi: bool = False): ''' 将dv区段对象转换为mido.MidiTrack对象 默认使用dv文件中的拼音,如果需要使用汉字,use_hanzi=True ''' import mido track = mido.MidiTrack() time = 0 for note in self.note: if (use_hanzi): track.append( mido.MetaMessage('lyrics', text=note.hanzi, time=(note.start - time))) else: track.append( mido.MetaMessage('lyrics', text=note.pinyin, time=(note.start - time))) track.append( mido.Message('note_on', note=note.notenum, velocity=64, time=0)) track.append( mido.Message('note_off', note=note.notenum, velocity=64, time=note.length)) time = note.start + note.length track.append(mido.MetaMessage('end_of_track')) return track
def to_midi_track(self): ''' 将ust文件对象转换为mido.MidiTrack对象 ''' import mido track = mido.MidiTrack() tick = 0 for note in self.note: if (note.isR()): tick += note.length else: track.append( mido.MetaMessage('lyrics', text=note.lyric, time=tick)) tick = 0 track.append( mido.Message('note_on', note=note.notenum, velocity=64, time=0)) track.append( mido.Message('note_off', note=note.notenum, velocity=64, time=note.length)) track.append(mido.MetaMessage('end_of_track')) return (track)
def multi_pianoroll_to_midi(file_name, bpm, pianoroll_dic): # 1.初始化 mid = mido.MidiFile() tracks = {} # 要保存的音轨信息 first_track = True midi_tempo = round(60000000 / bpm) # 这首歌的速度(每一拍多少微秒) # 2.保存音符 for key in pianoroll_dic: # 2.1.定义音轨名称/使用乐器等 tracks[key] = mido.MidiTrack() # 定义新的音轨 mid.tracks.append(tracks[key]) # 在midi中添加这个音轨 if first_track: tracks[key].append(mido.MetaMessage('set_tempo', tempo=midi_tempo, time=0)) # 设置歌曲的速度 first_track = False tracks[key].append(mido.MetaMessage('track_name', name=pianoroll_dic[key]['name'], time=0)) # 这个音轨的名称 tracks[key].append(mido.Message('program_change', program=pianoroll_dic[key]['program'], time=0, channel=key)) # 这个音轨使用的乐器 # 2.2.从piano_dict中获取音符列表并转化为midi message的形式 note_list = [] for note_it in pianoroll_dic[key]['note']: note_list.append(['on', note_it[0], note_it[1], note_it[2]]) note_list.append(['off', note_it[0] + note_it[3], note_it[1], note_it[2]]) note_list = sorted(note_list, key=lambda item: item[1]) # 按照音符的时间排序 # 2.3.往tracks中保存这些音符 current_note_time = 0 for note_it in note_list: if note_it[0] == 'on': tracks[key].append(mido.Message('note_on', note=note_it[2], velocity=note_it[3], time=round(480 * (note_it[1] - current_note_time)), channel=key)) elif note_it[0] == 'off': tracks[key].append(mido.Message('note_off', note=note_it[2], velocity=note_it[3], time=round(480 * (note_it[1] - current_note_time)), channel=key)) current_note_time = note_it[1] # 3.保存这个midi文件 mid.save(file_name)
def createMidiRhythmScore(midi_filename, onset_frames_index_of_16th_notes, strong_onset_frames_index_of_16th_notes, weak_onset_frames_index_of_16th_notes, bpm, auftakt_16th_notes_number=0): #MIDIデータの作成 #16分音符のtickでの単位あたりの長さ ticks_per_16th_note = 120 ticks_per_beat = ticks_per_16th_note * 4 #4分音符は480がデフォルト #各音符の配置される場所(tick) onset_ticks = np.array( onset_frames_index_of_16th_notes) * ticks_per_16th_note strong_onset_ticks = np.array( strong_onset_frames_index_of_16th_notes) * ticks_per_16th_note weak_onset_ticks = np.array( weak_onset_frames_index_of_16th_notes) * ticks_per_16th_note #auftaktの処理(本来mido自体をいじるべきだが便宜上ここで) #onset_ticks = list(filter(lambda x: x >= ticks_per_16th_note * auftakt_16th_notes_number, onset_ticks)) #strong_onset_ticks = list(filter(lambda x: x >= ticks_per_16th_note * auftakt_16th_notes_number, strong_onset_ticks)) #weak_onset_ticks = list(filter(lambda x: x >= ticks_per_16th_note * auftakt_16th_notes_number, weak_onset_ticks)) #事前処理 smf = mido.MidiFile(ticks_per_beat=ticks_per_beat) track = mido.MidiTrack() track.append(mido.MetaMessage('set_tempo', tempo=mido.bpm2tempo(bpm))) track.append(mido.Message('program_change', program=1)) #音色 #音符入力 #最初だけデルタタイム入れる onset_ticks_diff = np.diff(onset_ticks) #auftaktの処理 #track.append(mido.Message('note_off',time=(ticks_per_16th_note * 12))) track.append( mido.Message('note_off', time=(ticks_per_16th_note * 16) - (ticks_per_16th_note * auftakt_16th_notes_number))) i = 0 for i in range(len(onset_ticks) - 1): delta = onset_ticks[i + 1] - onset_ticks[i] if onset_ticks[i] in strong_onset_ticks: track.append( mido.Message('note_on', velocity=100, note=librosa.note_to_midi('F3'))) track.append(mido.Message('note_off', time=delta)) track.append( mido.Message('note_off', note=librosa.note_to_midi('F3'))) elif onset_ticks[i] in weak_onset_ticks: track.append( mido.Message('note_on', velocity=50, note=librosa.note_to_midi('A3'))) track.append(mido.Message('note_off', time=delta)) track.append( mido.Message('note_off', note=librosa.note_to_midi('A3'))) track.append(mido.MetaMessage('end_of_track')) smf.tracks.append(track) #midiの出力 smf.save(midi_filename)
def _make_metadata_track(name, time_signature, tempo, length): """Make a track of metadata events""" return [ mido.MetaMessage('track_name', name=name or 'unnamed', time=0), mido.MetaMessage('time_signature', numerator=time_signature[0], denominator=time_signature[1], time=0), mido.MetaMessage('set_tempo', tempo=mido.bpm2tempo(tempo), time=0), mido.MetaMessage('end_of_track', time=length) ]
def add_meta_messages(self, track: mido.MidiTrack) -> mido.MidiTrack: """ Adds meta messages to the beginning of the track including: - track name - instrument name """ meta_msgs = [ mido.MetaMessage("track_name", name="Main_Track", time=0), mido.MetaMessage("instrument_name", name="Piano", time=0), ] track = meta_msgs + track return track
def write_midi_notestream(tracks, ticks_per_beat, filename='result.mid', numerator=4, denominator=4, key=None): """Write note stream into midi file. Parameters ---------- track_list : list list of dict containing necessary info of a track. The format should be: { 'note_stream': notes_stream, 'name': track.name, 'is_drum': track.is_drum, 'program': track.program } ticks_per_beat : int beat resolution of a beat numerator : int time signature (numerator) denominator : int time signature (denominator) key : str key signature """ mid = mido.MidiFile(ticks_per_beat=ticks_per_beat) # meta data track meta_track = mido.MidiTrack() meta_track.append( mido.MetaMessage('time_signature', time=0, numerator=numerator, denominator=denominator)) if key is not None: meta_track.append(mido.MetaMessage('key_signature', time=0, key=key)) meta_track.append( mido.MetaMessage('end_of_track', time=meta_track[-1].time + 1)) mid.tracks.append(meta_track) for tidx, track in enumerate(tracks): track = write_track_notestream(track['note_stream'], program=track['program'], is_drum=track['is_drum'], name=track['name'], tidx=tidx) mid.tracks.append(track) mid.save(filename=filename)
def convert_numpy_to_midi(notes_np, output_name="exported_midi_from_numpy", upscale=1, tempo=500000): subset = np.array([v for v in notes_np for _ in range(upscale)]) mid_new = mido.MidiFile(ticks_per_beat=384) track_meta = mido.MidiTrack() track_notes = mido.MidiTrack() track_meta.append(mido.MetaMessage("set_tempo", tempo=tempo)) track_meta.append( mido.MetaMessage("time_signature", clocks_per_click=24, denominator=4, numerator=4, time=0, notated_32nd_notes_per_beat=8)) track_meta.append(mido.MetaMessage("end_of_track", time=1)) is_on_list = [False for _ in range(129)] time = 0 #to_append = (note,velo) to_append = (0, 0) for v in subset: is_on_list_old = is_on_list #get a copy for note, is_on in enumerate(v): cond1 = is_on and not is_on_list[note] cond2 = not is_on and is_on_list[note] if cond1 or cond2: #save prev note with correct time note_prev, velo_prev = to_append track_notes.append( mido.Message('note_on', note=note_prev, velocity=velo_prev, time=time)) time = 0 if cond1: #note just activated is_on_list[note] = True to_append = (note, 64) elif cond2: #note just deactivated is_on_list[note] = False to_append = (note, 0) #if note is playing and it has been noted in the list, then ignore time += 1 mid_new.tracks.append(track_meta) mid_new.tracks.append(track_notes) mid_new.save(output_name)
def matrixToMidi(midi_matrix, path): ticks_per_time_slice = 1 # 1 / 0.20 = 50 time_per_time_slice = 0.02 # do this in config bpm = 1 / time_per_time_slice ticks_per_beat = 60 * ticks_per_time_slice / (bpm * time_per_time_slice) midiFile = m.MidiFile(ticks_per_beat=int(ticks_per_beat)) track = m.MidiTrack() midiFile.tracks.append(track) track.append( m.MetaMessage('set_tempo', tempo=int(globals.microseconds_per_minute / bpm), time=0)) vector_dimension = 49 current_state = np.zeros(vector_dimension) last_event_index = 0 # highest_note = 81 # A5 # loweset_note = 33 # A1 for slice_index, time_slice in enumerate( np.concatenate((midi_matrix, np.zeros((1, vector_dimension))), axis=0)): # can change 1 to 0, and 0 to -1. note_changes = time_slice - current_state # compare previous time slice for note on OR note off event. Only make note on event when a time_slice starts a note for note_idx, note in enumerate(note_changes): if note == 1: note_event = m.Message('note_on', time=(slice_index - last_event_index) * ticks_per_time_slice, velocity=65, note=note_idx + globals.lowest_note) track.append(note_event) last_event_index = slice_index elif note == -1: note_event = m.Message('note_off', time=(slice_index - last_event_index) * ticks_per_time_slice, velocity=65, note=note_idx + globals.lowest_note) track.append(note_event) last_event_index = slice_index current_state = time_slice track.append(m.MetaMessage('end_of_track', time=1)) midiFile.save(path)
def addOrigin(midi_file, url, url_parts=[]): for i in range(0, len(url)): u = url[i] if (u != "https:" and u != ""): url_parts.append(u) details = "File Details: " for i in range(1, len(url_parts)): details = details + url_parts[i] + ", " print(midi_file.tracks[0]) midi_file.tracks[0].append(mido.MetaMessage('copyright', text=url_parts[0])) midi_file.tracks[0].append(mido.MetaMessage('text', text=details)) print(midi_file.tracks[0])
def write_tempo_map(self): # Figure out BPM, either from command line argument or from actual timing bpm = self.tempo_bpm if not bpm: end_time = time.time() delta = end_time - self.start_time beats = self.total_ticks / TICKS_PER_BEAT bpm = int(round(beats * 60 / delta)) print("BPM: %d" % bpm) # Write tempo and time signature to tempo map track self.tempo_map_track.append(mido.MetaMessage('set_tempo', tempo=mido.bpm2tempo(bpm))) self.tempo_map_track.append(mido.MetaMessage('time_signature', numerator=4, denominator=4))
def trackedit(track_program, track_velocity, track_name, filepath, isrighthand): str_file = open(filepath) str = str_file.read() str = "".join(str.split()) print(str) str_file.close() track_editing = mido.MidiTrack() track_editing.append( mido.Message("program_change", program=track_program, time=0)) track_editing.append( mido.MetaMessage("track_name", name=track_name, time=0)) # 音轨名 track_editing.append( mido.MetaMessage("time_signature", numerator=4, denominator=4, time=0)) # 拍号 track_editing.append(mido.MetaMessage("key_signature", key="C", time=0)) # 调号 track_editing.append(mido.MetaMessage("set_tempo", tempo=375000, time=0)) # 60,000,000uspm / 160bpm len = notelen_0 empty_len = 0 for i in str: i_note = C4 if i == ".": len = notelen_16 empty_len = notelen_1 continue elif isrighthand == True: i_note = righthand[int(i)] else: i_note = lefthand[int(i)] track_editing.append( mido.Message("note_on", note=i_note, velocity=track_velocity, time=empty_len)) track_editing.append( mido.Message("note_off", note=i_note, velocity=track_velocity, time=len)) empty_len = 0 mid1.tracks.append(track_editing)
def write_track_notestream(notes, program=0, is_drum=False, name=None, tidx=0): mtrack = mido.MidiTrack() if name is not None: mtrack.append(mido.MetaMessage('track_name', time=0, name=name)) # note to message event_list = [] for idx, note in enumerate(notes): st, duration, p, v = note if duration == 0: # warning event_list.append(('note_on', p, 0, st)) else: event_list.extend([('note_on', p, v, st), ('note_on', p, 0, st + duration)]) # sort by time event_list = sorted(event_list, key=lambda x: x[-1]) # set channel channels = list(range(16)) channels.remove(9) if is_drum: channel = 9 else: channel = channels[tidx % len(channels)] # set program mtrack.append( mido.Message('program_change', channel=channel, program=program, time=0)) # set notes current = 0 for idx, e in enumerate(event_list): delta = e[-1] - current current = e[-1] mtrack.append( mido.Message(e[-0], channel=channel, note=e[1], velocity=e[2], time=delta)) # add end of track mtrack.append(mido.MetaMessage('end_of_track', time=mtrack[-1].time + 1)) return mtrack
def convertEventsToMidi(events: list): ''' takes in a list of MidiEvents and returns a Midi object ''' midievents = [] for event in events: heapq.heappush(midievents, (event.time_on, "on", event.note, event.velocity)) heapq.heappush(midievents, (event.time_off, "off", event.note, event.velocity)) midievents = [heapq.heappop(midievents) for x in range(len(midievents))] mid = mido.MidiFile() t = mid.add_track(name="Test Track") lastTick = 0 for ev in midievents: tick = mido.second2tick(ev[0], mid.ticks_per_beat, 500000) tickDif = tick - lastTick lastTick = tick mType = "note_on" if ev[1] == "on" else "note_off" tickDif += 0.5 tickDif = math.floor(tickDif) message = mido.Message(mType, note=ev[2], time=tickDif) t.append(message) t.append(mido.MetaMessage("end_of_track")) return mid
def to_midi(self, bpm=120, low_c=48): midi = mido.MidiFile() track = mido.MidiTrack() midi.tracks.append(track) track.append(mido.MetaMessage('set_tempo', tempo=mido.bpm2tempo(bpm))) sec_per_sub = 60. / bpm / self.subdivisions_per_beat subdiv_delta = int( mido.second2tick(sec_per_sub, midi.ticks_per_beat, mido.bpm2tempo(bpm))) current_delta = 0 last_time = 0 note_on_events = [('note_on', i.note, i.time) for i in self.__notes] note_off_events = [('note_off', i.note, i.time + i.length) for i in self.__notes] note_events = sorted(note_on_events + note_off_events, key=lambda x: x[2]) for note_type, note, time in note_events: current_time = int((time - last_time) * subdiv_delta) track.append( mido.Message(note_type, note=note + low_c, velocity=80, time=current_time)) last_time = time return midi
def set_tempo_msg(): nonlocal track_time, time_diff tmp_time_diff = time_diff trk.append(mido.MetaMessage('set_tempo', tempo=current_tempo)) track_time += time_diff time_diff = 0 return 'set_tempo{time=%d, tempo=%d}' % (tmp_time_diff, current_tempo)
def createMidi(tempo, bahp_points): """ Create a mido.MidiFile object from an initial tempo (int) and a list of bahp points (each element is a tuple: (tick, pitch, velocity, duration)) """ assertMido('to') bahp_points.sort() # MIDI setup midi = mido.MidiFile(type=0, ticks_per_beat=QUARTER_NOTE) track = mido.MidiTrack() midi.tracks.append(track) # Tempo track.append(mido.MetaMessage('set_tempo', tempo=mido.bpm2tempo(tempo), time=0)) # Bahps (notes) current_time = 0 for t, p, v, d in bahp_points: track.append(mido.Message('note_on', note=p, velocity=v, time=(t - current_time))) track.append(mido.Message('note_off', note=p, velocity=0, time=d)) current_time = t + d return midi
def save(score: panscore.Score, filename: str): #将panscore.Score对象保存为文件 mid = mido.MidiFile() for tr in score.track: messages: List[Tuple[int, mido.Message]] = [] #[(绝对时间,midi事件)] #把音符转换为midi事件序列 for n in tr.note: messages.append( (n.start, mido.MetaMessage('lyrics', text=n.lyric, time=0))) messages.append((n.start, mido.Message('note_on', note=n.notenum, velocity=64, time=0))) messages.append((n.start + n.length, mido.Message('note_off', note=n.notenum, velocity=64, time=0))) #按时间排序 message = sorted(messages, key=lambda x: x[0]) #把时间差写入midi事件,并写入MidiTrack对象 time = 0 mtr = mido.MidiTrack() #mtr.append(mido.MetaMessage("track_name",name=tr.name,time=0)) for m in messages: m[1].time = m[0] - time mtr.append(m[1]) time = m[0] mid.tracks.append(mtr) mid.save(filename)
def reset(self): self.midi_file = mido.MidiFile() self.track = mido.MidiTrack() self.track.append(mido.MetaMessage('set_tempo', tempo=self.track_tempo)) # Tracks on notes self.on_notes = set()
def make_midi(input_wav, notes, tempo, mean_beat, instrument, velocity): mid = mido.MidiFile() track = mido.MidiTrack() mid.tracks.append(track) tempo = mido.bpm2tempo(tempo) track.append( mido.MetaMessage('set_tempo', tempo=round(tempo * slow), time=0)) track.append(mido.Message('program_change', program=instrument, time=0)) for note in notes: gap = int(round((note[1] * 480) / mean_beat)) if (note[0] == 'r'): track.append(mido.Message('note_on', note=60, velocity=0, time=0)) track.append( mido.Message('note_off', note=60, velocity=0, time=gap)) else: note_num = librosa.note_to_midi(note[0]) track.append( mido.Message('note_on', note=note_num, velocity=velocity, time=0)) track.append( mido.Message('note_off', note=note_num, velocity=velocity, time=gap)) output_midi = getFilename(input_wav, instrument) # mid.save(output_midi) return mid, output_midi
def np2MIDI(self, in_filename, out_filename, num = 4, den = 4, clocks = 36, noted32 = 8, AutoTimed = False, AutoTime=120): max_midi_time = 1000.0 data = np.load(in_filename) mid = mido.MidiFile() track = mido.MidiTrack() mid.tracks.append(track) num = 4 den = 4 clocks = 36 noted32 = 8 track.append(mido.MetaMessage('time_signature', numerator=num, denominator=den, clocks_per_click=clocks, notated_32nd_notes_per_beat=noted32, time=0)) test=[] for msg in data: if int(msg[0]+0.5) == 1: control = 'note_on' else: control = 'note_off' if AutoTimed: track.append(mido.Message(control, note=int(msg[1]*127), velocity=int(msg[2]*127), time=AutoTime)) else: track.append(mido.Message(control, note=int(msg[1]*127), velocity=int(msg[2]*127), time=int(msg[3]*max_midi_time))) if not out_filename[-4] == '.mid': out_filename += '.mid' mid.save(out_filename)
def add_drum(mid1, output_midi, tempo, mean_beat, beat_num, type, velocity): mid = mid1 track2 = mido.MidiTrack() mid.tracks.append(track2) tempo = mido.bpm2tempo(tempo) track2.append( mido.MetaMessage('set_tempo', tempo=round(tempo * slow), time=0)) gap = 480 for i in range(0, beat_num): track2.append(mido.Message('note_on', note=60, velocity=0, time=0)) track2.append(mido.Message('note_off', note=60, velocity=0, time=gap)) if (i % 2 == 1): track2.append(mido.Message('program_change', program=type, time=0)) # 这个音轨使用的乐器 track2.append( mido.Message('note_on', note=24, velocity=velocity - 30, time=0)) track2.append( mido.Message('note_off', note=24, velocity=velocity - 30, time=0)) else: track2.append(mido.Message('program_change', program=type, time=0)) # 这个音轨使用的乐器 track2.append( mido.Message('note_on', note=14, velocity=velocity, time=0)) track2.append( mido.Message('note_off', note=14, velocity=velocity, time=0)) output_midi = getFilename(output_midi, type) # mid.save(output_midi) return mid, output_midi
def tensor_to_msg_list(tensor): """ Returns a mido.Message() if tensor.shape[0] == 1. Otherwise, returns a mido.MidiTrack() Transforms the given tensor into the appropriate mido class Requires the tensor to be cleaned by clean_tensor() first mido will throw an error if the values are not in an appropriate range """ if tensor.shape == (INPUT_SIZE, ): msg_type = ACCEPTED_MESSAGES[tensor[:4].argmax()] msg_time = tensor[4] if msg_type == "end_of_track": msg = mido.MetaMessage("end_of_track") else: msg = mido.Message(msg_type, time=msg_time) if msg_type == 'program_change': msg.program = int(tensor[5]) elif msg_type == 'control_change': msg.control = int(tensor[6]) msg.value = int(tensor[7]) elif msg_type == 'note_on': msg.note = int(tensor[8]) msg.velocity = int(tensor[9]) return msg else: track = [] for i in tensor: track.append(tensor_to_msg_list(i)) return track
def from_midi(filename): midi = mido.MidiFile(filename) # convert to absolute time in beats and separate by channel if midi.type == 0: channels = __to_abs_time_per_channel_type_0(midi) if midi.type == 1: channels = __to_abs_time_per_channel_type_1(midi) # for every channel, find instrument instruments = list(map(__find_channel_instrument, channels[:-1])) # parse every tempo change tempo_times = [msg.time for msg in channels[-1] if msg.type == "set_tempo"] tempos = [] # if no tempo changes found, assume constant 120BPM throughout if len(tempo_times) == 0: tempo_times.append(0) channels[-1].insert( 0, mido.MetaMessage("set_tempo", time=0, tempo=mido.bpm2tempo(120))) for i in range(len(tempo_times) - 1): tempos.append( __parse_tempo(channels.copy(), instruments, tempo_times[i], tempo_times[i + 1])) tempos.append(__parse_tempo(channels.copy(), instruments, tempo_times[-1])) # combine all tempo fragmens into one sequence return Melody(tempos)
def write_header(self, mid, track, tempo): track.append(mido.MetaMessage('set_tempo', tempo=tempo)) try: track.append(mido.MetaMessage('key_signature', key=self.midi_key)) except ValueError: print( f"\n***ERROR: invalid key passed to MIDI renderer. Using {Resources.DEFAULT_KEY} instead." ) track.append( mido.MetaMessage('key_signature', key=Resources.DEFAULT_KEY)) track.append( mido.Message('program_change', program=self.midi_instrument, time=0))
def notes2mid(notes): mid = mido.MidiFile() track = mido.MidiTrack() mid.tracks.append(track) mid.ticks_per_beat = 480 new_tempo = mido.bpm2tempo(120.0) track.append(mido.MetaMessage('set_tempo', tempo=new_tempo)) track.append(mido.Message('program_change', program=0, time=0)) cur_total_tick = 0 for note in notes: if note[2] == 0: continue note[2] = int(round(note[2])) ticks_since_previous_onset = int(mido.second2tick( note[0], ticks_per_beat=480, tempo=new_tempo)) ticks_current_note = int(mido.second2tick( note[1]-0.0001, ticks_per_beat=480, tempo=new_tempo)) note_on_length = ticks_since_previous_onset - cur_total_tick note_off_length = ticks_current_note - note_on_length - cur_total_tick track.append(mido.Message( 'note_on', note=note[2], velocity=100, time=note_on_length)) track.append(mido.Message( 'note_off', note=note[2], velocity=100, time=note_off_length)) cur_total_tick = cur_total_tick + note_on_length + note_off_length return mid