def pianorollToMidi(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'], 0) 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") reverse_dic = {value: key for key, value in dictionary_dict.items()} piano_tmp = np.zeros((len(piano_roll), 128)) # id_array = np.argwhere(piano_roll == 1)[:, 1] for i in range(len(piano_roll)): notes_list = eval(reverse_dic[piano_roll[i]]) if notes_list is None: break elif len(notes_list) == 0: continue else: piano_tmp[i, notes_list] = CONFIG['velocity'] piano_roll = piano_tmp 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 generate_multiple_tracks_from_numpy_matrices(self, num, dir, files, size, names, are_drums, tempo, downbeat, beat_resolution, programs=None, save_fig=False, save_path=None): tracks = [] for i in range(num): path = dir + files[i] name = names[i] if programs == None: program = 0 else: program = programs[i] is_drum = are_drums[i] piano_roll = np.load(path) piano_roll.resize(size) track = Track(piano_roll, program, is_drum, name) tracks.append(track) multitrack = Multitrack(tracks=tracks, tempo=tempo, downbeat=downbeat, beat_resolution=beat_resolution) multitrack.save(dir + 'multi.npz') fig, axs = pypianoroll.multitrack.plot_multitrack(multitrack, grid_linewidth=0.8, ytick='off') if save_fig: plt.savefig(save_path) else: plt.show()
def write_song(song, path, data_config): """Writes multi-track pianoroll song into a MIDI file. Saves the song using the `pypianoroll` package. Args: song: A song pianoroll array, sized `[time_steps, 128, num_tracks]`. path: A path where the song should be saved. data_config: A data configuration dictionary. """ song = song * 100. instruments = data_config['instruments'] tracks = [] for i in range(len(instruments)): name = instruments[i] track = np.take(song, i, axis=-1) # Manually adjusting the sound if name == 'Piano': track = track * 0.8 elif name == 'Strings': track = track * 0.9 elif name == 'Bass': track = track * 1.2 track = Track( pianoroll=track, program=data_config['programs'][i], is_drum=data_config['is_drums'][i]) tracks.append(track) mtrack = Multitrack( tracks=tracks, tempo=data_config['tempo'], beat_resolution=data_config['beat_resolution']) mtrack.write(path)
def get_melody_track(self, program=0): if self.melody is None: return None bottom, top = self.meta.get('melody_pitch_range', [0, 128]) offset = self.meta.get('melody_offset', 0) melody_vocab_size = self.meta.get('melody_vocab_size', 128) step_len = len(self.melody) if self.melody.ndim == 1: nproll = np.zeros([step_len, 128], dtype=bool) nproll[np.arange(step_len), offset + self.melody] = True nproll[:, :offset + bottom], nproll[:, offset + top:offset + melody_vocab_size] = False, False elif self.melody.ndim == 2: nproll = np.zeros([step_len, 128], dtype=self.melody.dtype) nproll[:, offset:offset + top - bottom] = self.melody[:, bottom:top] else: raise ValueError("melody must be ndim==1 or ndim==2") return Track(nproll, program=program, name='melody')
def play_notes(self, show_map=False): """ Converts the notes array to pypianoroll format and then using MultiTrack object, the midi file is written to the file system :return: """ # print(self.programs) pianorolls = [] for track in self.notes: pianoroll = np.zeros((track.shape[1] * 3, 128)) for i in range(track.shape[0]): note_track = np.array(track[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 + self.dura_to_timecell(note_track[pos] - 1) + 1, 83 - i] = 90 pianorolls.append(pianoroll) # print("pianoroll") print(self.notes_index) tracks = [] for i in range(len(pianorolls)): tracker = Track(pianoroll=pianorolls[i], program=self.programs[i]) tracks.append(tracker) multitrack = Multitrack(tracks=tracks) multitrack.write("create1.mid") if show_map: print("Show map will not work")
def process_single(net, start, seq_size, global_lower, beat_resolution=2): """ Generate a single melody as a multitrack object :net: :start: starting note :seq_size: sequence size to generate :global_lower: minimal pitch of the voice :beat_resolution: :return: multitrack object for generated melody """ notes = sample(net, seq_size, prime=[start, start, start + 2, start + 2]) # put back to the pitch ranges pianoroll = unscale_pianoroll(notes, global_lower) # create a one_hot_pianoroll one_hot = one_hot_encode_pianoroll(pianoroll, 128) * 90 # store it a in a track object track = Track(pianoroll=one_hot, name='new track') # create a multitrack made of the generated track object multitrack = Multitrack(tracks=[track], tempo=90, beat_resolution=beat_resolution) return multitrack
gen_32th[idx_song,time,pitch,idx]=0.0 else: if cal > 0.6: gen_32th[idx_song,time,pitch,idx]=1.0 else: gen_32th[idx_song,time,pitch,idx]=0.0 #------------------# # write midi files # #------------------# gen_32th = np.reshape(gen_32th,[-1,128,8]) # 64 samples track_bass = Track(pianoroll=gen_32th[:,:,0], program=33, is_drum=False, name= 'bass') track_drum = Track(pianoroll=gen_32th[:,:,1], program=0, is_drum=True, name= 'drum') track_guitar = Track(pianoroll=gen_32th[:,:,2], program=25, is_drum=False, name= 'guitar') track_piano = Track(pianoroll=gen_32th[:,:,3], program=0, is_drum=False, name= 'piano') track_string = Track(pianoroll=gen_32th[:,:,4], program=41, is_drum=False, name= 'string') track_tt_mel = Track(pianoroll=gen_32th[:,:,5], program=61, is_drum=False, name= 'tt_mel') track_tt_cho = Track(pianoroll=gen_32th[:,:,6], program=0, is_drum=False, name= 'tt_cho') track_madmom_cho = Track(pianoroll=gen_32th[:,:,7], program=0, is_drum=False, name= 'madmom_cho')
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: tempo_arr = np.full(length, 120.0) 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 tempo_arr[position:] = qpm # Downbeats if not music.downbeats: downbeat_arr = None else: downbeat_arr = np.ones(length, bool) for downbeat in music.downbeats: downbeat_arr[downbeat] = True has_title = music.metadata is not None and music.metadata.title is not None return Multitrack( name=music.metadata.title if has_title else None, resolution=music.resolution, tempo=tempo_arr, downbeat=downbeat_arr, tracks=tracks, )
def make_a_track(eight_bar_binarized, track_name='melody', instrument=0): track = Track(pianoroll=eight_bar_binarized, program=instrument, is_drum=False) return track
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 and m[i + 1] == m[i]: 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, 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 + ".mid")
def main(): """Main function.""" num_consecutive_bar = 4 resolution = 12 down_sample = 2 count_total_segments = 0 ok_segment_list = [] hop_size = num_consecutive_bar / 4 args = parse_arguments() if args.recursive: filenames = args.input_dir.rglob("*.mid") else: filenames = args.input_dir.glob("*.mid") for filename in filenames: print(f"Processing {filename}") multitrack = Multitrack(filename) downbeat = multitrack.downbeat num_bar = len(downbeat) // resolution hop_iter = 0 song_ok_segments = [] for bidx in range(num_bar - num_consecutive_bar): if hop_iter > 0: hop_iter -= 1 continue st = bidx * resolution ed = st + num_consecutive_bar * resolution best_instr = [ Track(pianoroll=np.zeros((num_consecutive_bar * resolution, 128))) ] * 5 best_score = [-1] * 5 for track in multitrack.tracks: tmp_map = check_which_family(track) in_family = np.where(tmp_map)[0] if not len(in_family): continue family = in_family[0] tmp_pianoroll = track[st:ed:down_sample] is_ok, score = segment_quality( tmp_pianoroll, FAMILY_THRESHOLDS[family][0], FAMILY_THRESHOLDS[family][1], ) if is_ok and sum(score) > best_score[family]: track.name = FAMILY_NAMES[family] best_instr[family] = track[st:ed:down_sample] best_score[family] = sum(score) hop_iter = np.random.randint(0, 1) + hop_size song_ok_segments.append( Multitrack(tracks=best_instr, beat_resolution=12)) count_ok_segment = len(song_ok_segments) if count_ok_segment > 6: seed = (6, count_ok_segment // 2) if count_ok_segment > 11: seed = (11, count_ok_segment // 3) if count_ok_segment > 15: seed = (15, count_ok_segment // 4) rand_idx = np.random.permutation(count_ok_segment)[:max(seed)] song_ok_segments = [song_ok_segments[ridx] for ridx in rand_idx] ok_segment_list.extend(song_ok_segments) count_ok_segment = len(rand_idx) else: ok_segment_list.extend(song_ok_segments) count_total_segments += len(song_ok_segments) print( f"current: {count_ok_segment} | cumulative: {count_total_segments}" ) print("-" * 30) print(count_total_segments) num_item = len(ok_segment_list) compiled_list = [] for lidx in range(num_item): multi_track = ok_segment_list[lidx] pianorolls = [] for tracks in multi_track.tracks: pianorolls.append(tracks.pianoroll[:, :, np.newaxis]) pianoroll_compiled = np.reshape( np.concatenate(pianorolls, axis=2)[:, 24:108, :], (num_consecutive_bar, resolution, 84, 5), ) pianoroll_compiled = pianoroll_compiled[np.newaxis, :] > 0 compiled_list.append(pianoroll_compiled.astype(bool)) result = np.concatenate(compiled_list, axis=0) print(f"output shape: {result.shape}") if args.outfile.endswith(".npz"): np.savez_compressed( args.outfile, nonzero=np.array(result.nonzero()), shape=result.shape, ) else: np.save(args.outfile, result) print(f"Successfully saved training data to : {args.outfile}")
plt.hist(outputs[:, 0, :].cpu().view(-1).detach().numpy(), bins=10, log=True) # %% plt.hist(ground_truth[:, 0, :].cpu().view(-1), bins=10, log=True) # %% # torch.save(net.state_dict(), 'Data/Model/test_100_epoch_modified_nn') # %% # Pianoroll to Midi from pypianoroll import Multitrack, Track # %% track = Track(pianoroll=nn.ReLU()(outputs[:, 0, :]).cpu().detach().numpy(), program=0) multitrack = Multitrack(tracks=[track]) multitrack.write(os.path.join(path_to_code, "Data/Temp/temp.mid")) # %% # Play Midi import pygame pygame.init() # %% pygame.mixer.music.load(os.path.join(path_to_code, "Data/Temp/temp.mid")) pygame.mixer.music.play() # %%
def remove_zero_at_end(piano_roll): # shape of piano roll should be (sequence length, number of pitches) valid = np.any(piano_roll, axis=1) pos = np.argwhere(valid).max() return piano_roll[:pos + 1, :] # %% path_to_code = "" # %% midi_data = pretty_midi.PrettyMIDI("Data/Train/chpn-p1.mid") # %% track = Track(pianoroll=midi_data.get_piano_roll(fs=100).transpose(), program=0) # %% # The value of tempo doesn't matter, what's matter is beat_resolution=int(60.0 / tempo * fs) multitrack = Multitrack( tracks=[track], # tempo=np.full(track.pianoroll.shape[0], midi_data.estimate_tempo()), tempo=np.full(track.pianoroll.shape[0], 6000), # beat_resolution=int(60.0 / midi_data.estimate_tempo() * 100) beat_resolution=int(60.0 / 6000 * 100) # tempo=midi_data.get_tempo_changes()[1], ) # %% multitrack.write("temp.mid")
multitrack = Multitrack(beat_resolution=4, name=os.path.splitext(l[i])[0]) x = pretty_midi.PrettyMIDI(os.path.join('./Jazz/', l[i])) multitrack.parse_pretty_midi(x) category_list = {'Piano': [], 'Drums': []} program_dict = {'Piano': 0, 'Drums': 0} for idx, track in enumerate(multitrack.tracks): if track.is_drum: category_list['Drums'].append(idx) else: category_list['Piano'].append(idx) tracks = [] merged = multitrack[category_list['Piano']].get_merged_pianoroll() merged = multitrack.get_merged_pianoroll() #print('ok') #print(merged.shape + ' merged shape') tracks = [(Track(merged, program=0, is_drum=False, name=os.path.splitext(l[i])[0]))] mt = Multitrack(None, tracks, multitrack.tempo, multitrack.downbeat, multitrack.beat_resolution, multitrack.name) #mt.write(os.path.join(ROOT_PATH, '-Study No.2 opus.105.mid')) pr = get_bar_piano_roll(merged) #print(pr.shape + ' pr shape') pr_clip = pr[:, :, 24:108] #print(pr_clip.shape) #print(pr_clip.shape + ' pr clip shape') if int(pr_clip.shape[0] % 4) != 0: pr_clip = np.delete(pr_clip, np.s_[-int(pr_clip.shape[0] % 4):], axis=0) pr_re = pr_clip.reshape(-1, 64, 84, 1) #print(pr_re.shape) #print(pr_re.shape + ' pr re shape') #save_midis(pr_re, os.path.join('/test/', os.path.splitext(l[i])[0] +'.mid')) #save_midis(pr_re, os.path.join('./test-mid/', os.path.splitext(l[i])[0] + '.mid')) #print(pr_re.shape)
data_new[time, note, track] = (time1 or time2) np.save('./lpd_4dbar_12/tra/tra_phr.npy', data_new) print('data_save') ################################## # pianoroll.mid # ################################## data_new = np.load('./lpd_4dbar_12/tra/tra_phr.npy') data_new_reshape = np.reshape(data_new, (-1, 384, 84, 5)) gen_pr = np.zeros((len(data_new_reshape[:]), 384, 128, 5), dtype=bool) gen_pr[:, :, 24:108, :] = data_new_reshape # Create a `pypianoroll.Track` instance # program can be choosed to apply various instruments for idx in range(0, len(gen_pr)): track_bass = Track(pianoroll=gen_pr[idx, :, :, 0], program=33, is_drum=False, name='bass') track_drum = Track(pianoroll=gen_pr[idx, :, :, 1], program=0, is_drum=True, name='drum') track_guitar = Track(pianoroll=gen_pr[idx, :, :, 2], program=25, is_drum=False, name='guitar') track_piano = Track(pianoroll=gen_pr[idx, :, :, 3], program=0, is_drum=False, name='piano') track_string = Track(pianoroll=gen_pr[idx, :, :, 4], program=41,
def pianoroll2midi(pianoroll, file_path): track = Track(pianoroll=pianoroll) multitrack = Multitrack(tracks=[track], tempo=GLOBAL_VAR.MIDI_TEMPO) multitrack.to_pretty_midi() multitrack.write(file_path)