def pianoroll2Midi(piano_roll: np.array, name="test_midi", dir="../output/", velocity=False, # True if the input array contains velocity info (means not binary but continuous) dictionary_dict = None # True if the using the dic mode ): if dictionary_dict is None: if velocity: piano_roll = np.floor(piano_roll * CONFIG['velocity_high']) piano_roll = np.clip(piano_roll, a_min=CONFIG['velocity_low'], a_max=CONFIG['velocity_high']) else: # fill in the default velocity piano_roll = np.where(piano_roll == 1, CONFIG['velocity'], piano_roll) else: # making sure this they are all one-hot vecotr (time_length, 128) # if not np.all(np.sum(piano_roll, axis=1) == 1): # raise ValueError("This is not one-hot vector") piano_roll = embedding2pianoroll(piano_roll, dictionary_dict) make_sure_path_exists(dir) track = Track(piano_roll, is_drum=False, name="piano") multi_track = Multitrack(tracks=[track], tempo=CONFIG['tempo'], downbeat=None, beat_resolution=CONFIG['beat_resolution'], ) file_name = os.path.join(dir, name if name.endswith(".mid") else name+".mid") multi_track.write(file_name)
def main(): if len(sys.argv) < 2: print("Please include experiment directory path.") return 1 elif not os.path.exists(sys.argv[1]): print("Experiment path does not exist.") return 1 else: exp_path = sys.argv[1] # for t in ['fake_x_bernoulli_sampling', 'fake_x_hard_thresholding']: # for i in range(10): # result_path = os.path.join(exp_path, 'results/inference/pianorolls/{}/{}_{}.npz'.format(t, t, i)) # m = Multitrack(result_path) # m.write(os.path.join(exp_path, 'results/inference/pianorolls/{}/result_{}.mid'.format(t, i))) # print(t, i) method = 'fake_x_hard_thresholding' for i in range(10): result_path = os.path.join( exp_path, 'results/inference/pianorolls/{}/{}_{}.npz'.format( method, method, i)) m = Multitrack(result_path) m.write( os.path.join( exp_path, 'results/inference/pianorolls/{}/result_{}.mid'.format( method, i))) print(method, i)
def convert_midi_files(): """Save a multi-track piano-roll converted from a MIDI file to target dataset directory and update MIDI information to `midi_dict`""" converter_root_dir = 'E:/MIDI_converted' root_dir = 'E:/free_MIDI' midi_collection = get_midi_collection() for midi in midi_collection.find({'Converted': False}): genre = midi['Genre'] name = midi['Name'] performer = midi['Performer'] filepath = root_dir + '/' + genre + '/' + name + ' - ' + performer + '.mid' try: midi_name = os.path.splitext(os.path.basename(filepath))[0] multitrack = Multitrack(beat_resolution=24, name=midi_name) pm = PrettyMIDI(filepath) midi_info = get_midi_info(pm) multitrack = Multitrack(filepath) merged = get_merged(multitrack) os.chdir(converter_root_dir) if not os.path.exists(converter_root_dir + '/' + genre): os.mkdir(converter_root_dir + '/' + genre) converter_path = converter_root_dir + '/' + genre + '/' + midi_name + '.npz' # merged.save(converter_path) print(get_midi_info(pm)) ''' midi_collection.update_one( {'_id', midi['_id']}, {'$set' :{'Converted': True}} ) ''' # print([midi_name, midi_info]) except: print(filepath) print(traceback.format_exc())
def get_dataset_metrics(dir="./generated_samples", base_term="unconditional"): """ Get harmonicity metric for a dataset provided by a directory and base_term. Assumes samples are of the form <base_term>_<index>_<bass/melody>.mid. """ bass_metrics = np.zeros((100, 3)) melody_metrics = np.zeros((100, 3)) harmonicity = np.zeros(100) tonal_matrix = get_tonal_matrix() for array_index, track_index in enumerate(range(0, 300, 3)): bass_track = Multitrack(os.path.join(dir, "{}_{}_bass.mid".format(base_term, track_index))) melody_track = Multitrack(os.path.join(dir, "{}_{}_melody.mid".format(base_term, track_index))) bass_pianoroll = bass_track.tracks[0].pianoroll melody_pianoroll = melody_track.tracks[0].pianoroll chroma_bass = to_chroma(bass_pianoroll) chroma_melody = to_chroma(melody_pianoroll) harmonicity[array_index] = get_harmonicity(chroma_melody, chroma_bass, 50, tonal_matrix = tonal_matrix) bass_metrics[array_index,:] = get_metrics(bass_pianoroll) melody_metrics[array_index, :] = get_metrics(melody_pianoroll) return harmonicity
def play_notes(roll, loc, trackname): """ Converts the notes array to pypianoroll format and then using MultiTrack object, the midi file is written to the file system :return: """ pianoroll = np.zeros((roll.shape[1] * 3, 128)) for i in range(roll.shape[0]): note_track = np.array(roll[i, :]) note_track += 1 notes_pos = np.nonzero(note_track) f = 3 for pos in notes_pos[0]: # print("Error", f * pos, f * pos + self.dura_to_timecell(note_track[pos] - 1),self.dura_to_timecell(note_track[pos] - 1)) pianoroll[f * pos:f * pos + dura_to_timecell(note_track[pos] - 1) + 1, 83 - i] = 90 tracks = [] tracker = Track(pianoroll=pianoroll, program=1) tracks.append(tracker) multitrack = Multitrack(tracks=tracks) # print(save_time, ) if len(np.nonzero(pianoroll)[0]) > 0: # for preventing writing empty midi tracks multitrack.write(loc + trackname)
def __getitem__(self, index): full_filename = self.full_filenames[index] multitrack = Multitrack(full_filename) multitrack.clip(0, 1) piano_roll = multitrack.tracks[0].pianoroll[::6, :] return torch.FloatTensor(piano_roll.astype(float))
def ppr_by_path(self, path, with_row=True, verbose=True): absolute_path = os.path.join(self.base_dir, path) if verbose: print(f"path: {path}") if with_row: row = self.df[self.df['path'] == path] row = row.T.squeeze() return Multitrack(absolute_path), row return Multitrack(absolute_path)
def binarizer(filepath, src, dst): """Load and binarize a multitrack pianoroll and save the resulting multitrack pianoroll to the destination directory.""" # Load and binarize the multitrack pianoroll multitrack = Multitrack(filepath) multitrack.binarize() # Save the binarized multitrack pianoroll result_path = change_prefix(filepath, src, dst) make_sure_path_exists(os.path.dirname(result_path)) multitrack.save(result_path)
def write_midi(filepath, pianorolls, program_nums=None, is_drums=None, track_names=None, velocity=100, tempo=120.0, beat_resolution=24): """ Write the given piano-roll(s) to a single MIDI file. Arguments --------- filepath : str Path to save the MIDI file. pianorolls : np.array, ndim=3 The piano-roll array to be written to the MIDI file. Shape is (num_timestep, num_pitch, num_track). program_nums : int or list of int MIDI program number(s) to be assigned to the MIDI track(s). Available values are 0 to 127. Must have the same length as `pianorolls`. is_drums : list of bool Drum indicator(s) to be assigned to the MIDI track(s). True for drums. False for other instruments. Must have the same length as `pianorolls`. track_names : list of str Track name(s) to be assigned to the MIDI track(s). """ if not np.issubdtype(pianorolls.dtype, np.bool_): raise TypeError("Support only binary-valued piano-rolls") if isinstance(program_nums, int): program_nums = [program_nums] if isinstance(is_drums, int): is_drums = [is_drums] if pianorolls.shape[2] != len(program_nums): raise ValueError("`pianorolls` and `program_nums` must have the same" "length") if pianorolls.shape[2] != len(is_drums): raise ValueError("`pianorolls` and `is_drums` must have the same" "length") if program_nums is None: program_nums = [0] * len(pianorolls) if is_drums is None: is_drums = [False] * len(pianorolls) multitrack = Multitrack(beat_resolution=beat_resolution, tempo=tempo) for idx in range(pianorolls.shape[2]): if track_names is None: track = Track(pianorolls[..., idx], program_nums[idx], is_drums[idx]) else: track = Track(pianorolls[..., idx], program_nums[idx], is_drums[idx], track_names[idx]) multitrack.append_track(track) multitrack.write(filepath)
def notes_to_midi(self, run_folder, output, filename=None): # 배치를 미디로 변환 binarized = output > 0 # 1. 이진화 # 1. reshpae (마디 부분합치기) score = binarized.reshape(-1, binarized.shape[1] * binarized.shape[2], binarized.shape[3], binarized.shape[4]) # 2. 마디 합치기 # 2. pad설정 pad_width = ((0, 0), (0, 0), (24, 20), (0, 0)) # 3. pad적용 score = np.pad(score, pad_width, 'constant') # 3. 패드 적용 # 4. reshape(-1, pitches, Track) score = score.reshape(-1, score.shape[2], score.shape[3]) # 4. reshape ( -1, 피치 수, 트랙) # 5. multitrack 생성 multitrack = Multitrack(beat_resolution=24, tempo=120) # 4.4. Multitrack 생성 ''' for j in range(score.shape[2]) :#4.5. 트랙수만큼 반복한다. track = Track(score[..., j])#4.5.1. Track 생성(painorools[..., idx], program_nums, is_drums) multitrack.append_track(track)#4.5.2. Multitrack 에 추가한다. ''' track = Track(score[..., 0]) multitrack.append_track(track) if run_folder != None: multitrack.write('{}/{}.mid'.format(run_folder, filename)) else: multitrack.write('{}.mid'.format('sample'))
def writeToMidi(self, midiPath): """Saves the piano roll data in a midi file. Parameters ---------- midiPath : str Folder in which the corresponding midi data is saved. """ tempTrack = StandardTrack(pianoroll=self.pianoroll, program=0, is_drum=False, name=self.name) tempMulti = Multitrack(tracks=(tempTrack, )) tempMulti.write(midiPath)
def get_sample(search_dir, fmt='mp3'): sound_paths = glob.glob(os.path.join(search_dir, f"*.{fmt}")) sound_paths.sort() if len(sound_paths) > 1: print(f"{len(sound_paths)} sounds found in {search_dir}") for i, path in enumerate(sound_paths): print(f"{i}: {path.split('/')[-1]}") idx = input("input the number of sound(empty for the last):") or -1 sound_path = sound_paths[int(idx)] elif sound_paths: sound_path = sound_paths[0] else: print(f"no sound file found in {search_dir}") return (None, None) print(f"sound is loaded from {sound_path}") song_name = sound_path.split('/')[-1].split('.')[0] midi_path = os.path.join(search_dir, f'{song_name}.midi') if os.path.exists(midi_path): ppr = Multitrack(midi_path) print(f"midi is loaded from {midi_path}") return (Audio(sound_path), ppr) else: print(f"failed to load midi from {midi_path}") return (Audio(sound_path), None)
def saveMidiFile(self, midiFileName, divider=16): print('saveMidiFile') length = sum(item[1] for item in self.humming) pianoRoll = np.zeros((length * divider, 128), dtype=np.int8) time = 0 for (p, l) in self.humming: pianoRoll[time:time + l * divider - 1, p] = 100 time += l * divider track = Track(pianoroll=pianoRoll, program=0, name='') multitrack = Multitrack(tracks=[track], beat_resolution=2 * divider, tempo=round(30 / self.sampleStepLength / self.beatResolution)) print("sampleStepLength :", self.sampleStepLength) print("beatResolution :", self.beatResolution) multitrack.write(midiFileName)
def load_from_midi_file(self, midi_file_path, use_custom_multitrack): """ midi_file_path: String that is path to a midi file to load. This midi file is assumed to have a beat resolution of 24. A merged and binarized numpy array (time_steps, 128) in shape is loaded into self.array. """ if use_custom_multitrack: multitrack = CustomMultitrack(filename=midi_file_path) else: multitrack = Multitrack(filename=midi_file_path) multitrack.check_validity() if multitrack.beat_resolution != 24: raise Exception( "Beat resolution of all midi files should be 24. Encountered beat resolution is " + str(multitrack.beat_resolution)) multitrack.merge_tracks( track_indices=[i for i in range(len(multitrack.tracks))], mode='max', program=0, remove_merged=True) pianoroll_array = (multitrack.tracks[0].pianoroll > 0.0).astype('bool') if (pianoroll_array.shape[0] == 0) or (pianoroll_array.shape[1] != 128): raise Exception( "Shape of pianoroll array should be (timesteps, 128), where timesteps > 0. Encountered shape is " + str(pianoroll_array.shape)) self.array = pianoroll_array
def get_merged(multitrack): """Merge the multitrack pianorolls into five instrument families and return the resulting multitrack pianoroll object.""" track_lists_to_merge = [[] for _ in range(5)] for idx, track in enumerate(multitrack.tracks): if track.is_drum: track_lists_to_merge[0].append(idx) elif track.program // 8 == 0: track_lists_to_merge[1].append(idx) elif track.program // 8 == 3: track_lists_to_merge[2].append(idx) elif track.program // 8 == 4: track_lists_to_merge[3].append(idx) elif track.program < 96 or 104 <= track.program < 112: track_lists_to_merge[4].append(idx) tracks = [] for idx, track_list_to_merge in enumerate(track_lists_to_merge): if track_list_to_merge: merged = multitrack[track_list_to_merge].get_merged_pianoroll( 'max') tracks.append( Track(merged, TRACK_INFO[idx][1], (idx == 0), TRACK_INFO[idx][0])) else: tracks.append( Track(None, TRACK_INFO[idx][1], (idx == 0), TRACK_INFO[idx][0])) return Multitrack(None, tracks, multitrack.tempo, multitrack.downbeat, multitrack.beat_resolution, multitrack.name)
def get_music_metrics(input_midi, beat_resolution, track=0): """Takes a midifile as an input and Returns the following metrics :param input_midi: Path to midi file :param beat_resolution: :param trac: Instrument number in the multi track midi file :return: The following metrics are returned 1.) n_pitch_classes_used is the unique pitch classes used in a pianoroll. 2.) polyphonic_rate ie ratio of the number of time steps where the number of pitches being played is larger than `threshold` to the total number of time steps in a pianoroll 3.) in_scale_rate is the ratio of the number of nonzero entries that lie in a specific scale to the total number of nonzero entries in a pianoroll. 4.) n_pitches_used is the the number of unique pitches used in a pianoroll.""" midi_data = Multitrack(input_midi, beat_resolution) piano_roll = midi_data.tracks[track].pianoroll n_pitch_classes_used = pypianoroll.metrics.n_pitch_classes_used(piano_roll) polyphonic_rate = pypianoroll.metrics.polyphonic_rate(piano_roll) in_scale_rate = pypianoroll.metrics.in_scale_rate(piano_roll) n_pitches_used = pypianoroll.metrics.n_pitches_used(piano_roll) metrics = [ n_pitch_classes_used, polyphonic_rate, n_pitches_used, in_scale_rate ] metrics_table = [[ "n_pitch_classes_used", "in_scale_rate", "polyphonic_rate", "n_pitches_used" ], metrics] table = Texttable() table.add_rows(metrics_table) print(table.draw())
def main(): c=0 for filename in (glob.glob('drive/My Drive/Synth pop MIDI/*.mid')): mtrack = Multitrack(filename) mtrack.to_pretty_midi() #mtrack = remove_short_tracks(mtrack) orchestra = group_by_program(mtrack) l=len(mtrack.tracks) trackid=[x for x in range(l)] newmtrack, inst = merge_instrument(mtrack,orchestra,trackid) filename=filename[30:] if len(newmtrack.tracks)==4: c+=1 print(filename, len(newmtrack.tracks), inst, orchestra) newmtrack.write('drive/My Drive/Synth pop MIDI/four tracks with drum sum/'+filename) print(c)
def midi2numpy(filename, b): midi = Multitrack(filename, beat_resolution=12) m = midi.tracks[0].pianoroll c = midi.tracks[1].pianoroll bar = int(m.shape[0]/12/4) bar = int(bar - bar%8) unit = 3 x1 = np.zeros((bar*16, 49)) # 48~96 x2 = np.zeros((bar*16, 1)) for i in range(x1.shape[0]): if np.sum(m[i*unit]>0) > 0: x1[i, np.where(m[i*unit]>0)[0][0] - 48] = 1 else: x1[i, 48] = 1 if i != 0 and np.sum(m[i*unit]==m[i*unit-1]) == 128: x2[i,0] = 0 else: x2[i,0] = 1 unit = 12 y = np.zeros((bar*4, 12)) for i in range(y.shape[0]): if np.sum(c[i*unit]>0) > 0: for note in np.where(c[i*unit]>0)[0]%12: y[i, note] = 1 # 4bar x1 = x1.reshape((int(bar/b), 4, 16*49)) x2 = x2.reshape((int(bar/b), 4, 16)) x = np.concatenate([x1, x2], 2) y = y.reshape((int(bar/b), 4, 12*b)) return x, y
def get_merged(multitrack): """Return a `pypianoroll.Multitrack` instance with piano-rolls merged to five tracks (Bass, Drums, Guitar, Piano and Strings)""" category_list = {'Bass': [], 'Drums': [], 'Guitar': [], 'Piano': [], 'Strings': []} program_dict = {'Piano': 0, 'Drums': 0, 'Guitar': 24, 'Bass': 32, 'Strings': 48} for idx, track in enumerate(multitrack.tracks): if track.is_drum: category_list['Drums'].append(idx) elif track.program//8 == 0: category_list['Piano'].append(idx) elif track.program//8 == 3: category_list['Guitar'].append(idx) elif track.program//8 == 4: category_list['Bass'].append(idx) else: category_list['Strings'].append(idx) tracks = [] for key in category_list: if category_list[key]: merged = multitrack[category_list[key]].get_merged_pianoroll() tracks.append(Track(merged, program_dict[key], key == 'Drums', key)) else: tracks.append(Track(None, program_dict[key], key == 'Drums', key)) return Multitrack(None, tracks, multitrack.tempo, multitrack.downbeat, multitrack.beat_resolution, multitrack.name)
def make_a_demo(track1, track2, song_idx): sample_name = 'sample_' + str(song_idx) multitrack = Multitrack(tracks=[track1, track2], tempo=120.0, beat_resolution=4) return multitrack
def load_file(root_path): # parser the data dir_list = os.listdir(root_path) dir_list.sort() file_name = [] file_num = [] for dir in dir_list: tmp_name = os.listdir(os.path.join("./raw_classical_music_data",dir)) tmp_name.sort() file_name.append(tmp_name) file_num.append(len(tmp_name)) print("Num of file in each dir : " ,file_num) # Parse a MIDI file to a `pypianoroll.Multitrack` instance data_list = [] for i,dir in enumerate(dir_list): print("\rPhraser the data : %d/%d" %(i+1,len(dir_list)), end = "") for name in file_name[i]: file_path = os.path.join('./raw_classical_music_data',dir,name) tmp_pypianoroll = Multitrack(file_path) tmp_pypianoroll.remove_empty_tracks() tmp_pypianoroll.pad_to_multiple(length_Section*length_tab) tmp_np = tmp_pypianoroll.get_stacked_pianoroll() data_list.append(tmp_np) data_list = np.array(data_list) #np.save("all_data.npy",data_list) print("") print("finish praser the data...") return data_list
def gen_song(tempo, title, plot_proll=False): print('\n GENERATING SONG...') noise = np.random.normal(0, 1, (1, latent_space)) print(noise) new_song = playnotes( np.array(decoder([noise])).reshape(parts * seq_len, 128)) * 100 track = Track(new_song, name='test') if plot_proll: track.plot() plt.show() multitrack = Multitrack(tracks=[track], beat_resolution=beat_resolution, tempo=tempo) multitrack.write(title + '.mid') closest_song(noise)
def segment_song(msd_id): boundaries, labels = msaf.process(get_synthesized_path(msd_id), boundaries_id="olda", labels_id="scluster", feature="mfcc") # merge short segments new_boundaries = [boundaries[0]] new_labels = [labels[0]] for i in range(1, len(boundaries)): if (boundaries[i] - boundaries[i-1]) > MIN_SEGMENT_LEN: new_boundaries.append(boundaries[i]) new_labels.append(labels[i]) boundaries = new_boundaries labels = new_labels # calculate tick values for segments mt_midi = Multitrack(get_npz_path(msd_id)) tempo = mt_midi.tempo[0] beat_resolution = mt_midi.beat_resolution # beats/min * ticks/beat * min/sec = ticks/sec ticks_per_second = (tempo*mt_midi.beat_resolution) // 60 def get_nearest(num, nearest="downbeat"): if nearest == "beat": multiple = beat_resolution elif nearest == "downbeat": multiple = beat_resolution * 4 else: raise ValueError("Argument to get_nearest should be either 'beat' or 'downbeat'") factor = num // multiple remainder = num % multiple if remainder < (multiple // 2): ndb = multiple*factor else: ndb = multiple*(factor + 1) return ndb prev_l = -1 tick_boundaries = [] for b, l in zip(boundaries, labels): if l != prev_l: tick_boundaries.append(get_nearest(b*ticks_per_second, "downbeat")) else: tick_boundaries.append(get_nearest(b*ticks_per_second, "beat")) second_boundaries = [tb/ticks_per_second for tb in tick_boundaries] # change labels to letters and order letter_labels = [] label_map = dict() for label in labels: if label not in label_map: label_map[label] = string.ascii_uppercase[len(label_map)] letter_labels.append(label_map[label]) return second_boundaries, tick_boundaries, letter_labels
def to_pypianoroll(music: "Music") -> Multitrack: """Return a Music object as a Multitrack object. Parameters ---------- music : :class:`muspy.Music` Music object to convert. Returns ------- multitrack : :class:`pypianoroll.Multitrack` Converted Multitrack object. """ length = (music.get_end_time() // music.resolution + 1) * music.resolution # Tracks tracks = [] for track in music.tracks: pianoroll = np.zeros((length, 128)) for note in track.notes: if note.velocity is not None: pianoroll[note.time:note.end, note.pitch] = note.velocity else: pianoroll[note.time:note.end, note.pitch] = DEFAULT_VELOCITY track = Track( program=track.program, is_drum=track.is_drum, name=track.name if track.name is not None else "", pianoroll=pianoroll, ) tracks.append(track) # Tempos if not music.tempos: tempo_arr = None else: last_tempo_time = max((tempo.time for tempo in music.tempos)) tempo_arr = 120.0 * np.ones(last_tempo_time + 1) qpm = 120.0 position = 0 for tempo in music.tempos: tempo_arr[position:tempo.time] = qpm tempo_arr[tempo.time] = tempo.qpm position = tempo.time + 1 qpm = tempo.qpm if music.metadata is not None: name = music.metadata.title if music.metadata.title is not None else "" return Multitrack( resolution=music.resolution, tracks=tracks, tempo=tempo_arr, # downbeat=music.downbeats if music.downbeats else None, name=name, )
def numpy2midi(m, c, theta, filename): resolution = 12 ratio = int(resolution/4) # 3 bar = int(m.shape[0]/4) mr = m[:,-4:].flatten() m = np.argmax(m[:,:-4].reshape(m.shape[0]*4, 49), 1) midi_m = np.zeros((resolution*bar*4, 128)) for i in range(len(m)): if m[i] == 48: # stop continue if i+1 != len(m): if mr[i+1] > theta: midi_m[i*ratio:(i+1)*ratio - 1, m[i]+48] = 100 else: midi_m[i*ratio:(i+1)*ratio, m[i]+48] = 100 else: #i+1 != len(m) and mr[i+1] == 0: midi_m[i*ratio:(i+1)*ratio - 1, m[i]+48] = 100 # else: #i+1 == len(m): # midi_m[i*ratio:(i+1)*ratio - 1, m[i]+48] = 100 midi_c = np.zeros((resolution*bar*4, 128)) nextchord = -1 for i in range(len(c)): # round # midi_c[i*resolution:(i+1)*resolution-1, np.where(np.round(c[i])==1)[0]+48] = 100 # dot if np.sum(c[i]) == 0: chord = len(chord_composition)-1 else: chord = np.argmax( np.dot(chord_composition, c[i])/(np.linalg.norm(chord_composition, axis=1)+1e-5)/(np.linalg.norm(c)+1e-5) ) if i < len(c)-1 and i%4!=3: nextchord = np.argmax( np.dot(chord_composition, c[i+1])/(np.linalg.norm(chord_composition, axis=1)+1e-5)/(np.linalg.norm(c)+1e-5) ) else: nextchord = -1 main = int(chord/7) for j in np.where(chord_composition[chord]==1)[0]: if j < main: if chord == nextchord: midi_c[i*resolution:(i+1)*resolution, j+60] = 100 else: midi_c[i*resolution:(i+1)*resolution-1, j+60] = 100 else: if chord == nextchord: midi_c[i*resolution:(i+1)*resolution, j+48] = 100 else: midi_c[i*resolution:(i+1)*resolution-1, j+48] = 100 track_m = Track(pianoroll=midi_m, program=0, is_drum=False) track_c = Track(pianoroll=midi_c, program=0, is_drum=False) multitrack = Multitrack(tracks=[track_m, track_c], tempo=80.0, beat_resolution=resolution) pypianoroll.write(multitrack, filename)
def merger(filepath, src, dst): """Load and merge a multitrack pianoroll and save to the given path.""" # Load and merge the multitrack pianoroll multitrack = Multitrack(filepath) merged = get_merged(multitrack) # Save the merged multitrack pianoroll result_path = change_prefix(filepath, src, dst) make_sure_path_exists(os.path.dirname(result_path)) merged.save(result_path)
def converter(filepath): """Save a multi-track piano-roll converted from a MIDI file to target dataset directory and update MIDI information to `midi_dict`""" try: midi_name = os.path.splitext(os.path.basename(filepath))[0] multitrack = Multitrack(beat_resolution=24, name=midi_name) pm = pretty_midi.PrettyMIDI(filepath) midi_info = get_midi_info(pm) multitrack.parse_pretty_midi(pm) merged = get_merged(multitrack) make_sure_path_exists(converter_path) merged.save(os.path.join(converter_path, midi_name + '.npz')) return [midi_name, midi_info] except: return None
def midi2Pianoroll(filepath, merge=True, velocity=False, ): """Convert a MIDI file to a multi-track piano-roll and save the resulting multi-track piano-roll to the destination directory. Return a tuple of `midi_md5` and useful information extracted from the MIDI file. """ midi_md5 = os.path.splitext(os.path.basename(filepath))[0] # prettyMIDI = PrettyMIDI(filepath) # time_signiture = "" # if len(prettyMIDI.time_signature_changes)>0: # time_signiture = "{}/{}".format(prettyMIDI.time_signature_changes[0].numerator, # prettyMIDI.time_signature_changes[0].denominator) # if time_signiture == "": # raise ValueError(midi_md5 + " no timesigniture") # if time_signiture != CONFIG['time_signatures']: # warnings.warn(midi_md5 + "'s timesiniture is " + time_signiture + " != " + CONFIG['time_signatures']) # return None multitrack = Multitrack(filepath, beat_resolution=CONFIG['beat_resolution'], name=midi_md5) if merge: result = multitrack.get_merged_pianoroll(mode="max") else: result = multitrack.get_stacked_pianoroll() right = None left = None for each_track in multitrack.tracks: if each_track.name.strip().lower() == 'piano right': right = each_track.pianoroll if each_track.name.strip().lower() == 'piano left': left = each_track.pianoroll if right is None or left is None: return None result = np.stack([right, left], axis=2) if not velocity: result = np.where(result > 0, 1, 0) else: result = result / CONFIG['velocity_high'] return result
def midi2pianoroll(filename): ### Create a `pypianoroll.Multitrack` instance multitrack = Multitrack(filepath=filename + '.mid', tempo=120.0, beat_resolution=12) ### save pypianoroll pypianoroll.save(filename + '.npz', multitrack, compressed=True) data = pypianoroll.load(filename + '.npz') data_tracks = data.get_stacked_pianorolls() data_bool = data_tracks.astype(bool) np.save(filename + '.npy', data_bool)
def midiToPianoroll(filepath, merge=True, velocity=False, ): """Convert a MIDI file to a multi-track piano-roll and save the resulting multi-track piano-roll to the destination directory. Return a tuple of `midi_md5` and useful information extracted from the MIDI file. """ midi_md5 = os.path.splitext(os.path.basename(filepath))[0] multitrack = Multitrack(filepath, beat_resolution=CONFIG['beat_resolution'], name=midi_md5) if merge: result = multitrack.get_merged_pianoroll(mode="max") else: result = multitrack.get_stacked_pianoroll() if not velocity: result = np.where(result > 0, 1, 0) else: result = result / CONFIG['velocity_high'] return result
def tempo_unify(): midi_collection = get_midi_collection() root_dir = 'E:/free_midi_library/' test_path = './test.mid' unify_tempo = 90 original = Multitrack(test_path) original_tempo = get_midi_info(original.to_pretty_midi())['tempo'][0] merged_multi = get_merged(original) tracks_dict = {} length = 0 for track in merged_multi.tracks: if track.pianoroll.shape[0] != 0: length = track.pianoroll.shape[0] old_pianoroll = track.pianoroll for i in range(128): for j in range(length): print(track.pianoroll[j][i], end=' ') print() '''
def write_files_from_states( states, metrics, seed, kernel, f_name="./renderings/midi/t", title="tendril sequence", g=generate_pianoroll, steps=DEFAULT_SEQUENCE_STEPS, beat_duration=DEFAULT_BEAT_DURATION, save_json=False, save_midi=False, debug=False, ): # TODO: make it possible to alter parameters more easily pianoroll = g(states, steps, beat_duration) # Create a `pypianoroll.Track` instance track = Track(pianoroll=pianoroll, program=0, is_drum=False, name=title) mt = Multitrack(tracks=[track]) mid_file = "{f_name}.tendril.{ext}".format(f_name=f_name, ext="mid") json_file = "{f_name}.tendril_states.{ext}".format(f_name=f_name, ext="json") # Write MIDI file if save_midi: print("writing midi file to: ", mid_file) mt.write(mid_file) # Write JSON file states_serialized = [np.int32(s).tolist() for s in states] states_dict = {"states": states_serialized} # print("states", states) if json_file: print("writing tendril states to: {}".format(json_file)) # Save state info as json_file with open(json_file, "w") as json_file: json.dump(states_dict, json_file)
def converter(filepath, src, dst): """Convert a MIDI file to a multi-track piano-roll and save the resulting multi-track piano-roll to the destination directory. Return a tuple of `midi_md5` and useful information extracted from the MIDI file. """ try: midi_md5 = os.path.splitext(os.path.basename(filepath))[0] multitrack = Multitrack(beat_resolution=CONFIG['beat_resolution'], name=midi_md5) pm = pretty_midi.PrettyMIDI(filepath) multitrack.parse_pretty_midi(pm) midi_info = get_midi_info(pm) result_dir = change_prefix(os.path.dirname(filepath), src, dst) make_sure_path_exists(result_dir) multitrack.save(os.path.join(result_dir, midi_md5 + '.npz')) return (midi_md5, midi_info) except: return None