def _reconstruct(): log.info("Choosing a random sample and autoencoding it...") samples = glob(cfg.Paths.samples + "/*sample*.npz") sample = np.random.choice(samples) sample = np.load(sample) sample = sample['sample'] tracks = [] for track in range(sample.shape[0]): t = pproll.Track(pianoroll=sample[track, :, :], program=0) t = t.binarize() tracks.append(t) song = pproll.Multitrack(tracks=tracks, resolution=midi_cfg.resolution) song = song.set_nonzeros(1) pproll.write(multitrack=song, path=os.path.join(cfg.Paths.generated, "original.mid")) sample = dataset.preprocess_single(sample) e = best_encoder.predict(sample) d = best_decoder.predict(e) d = d.reshape((1, 1, midi_cfg.phrase_size, 130)) reconstructed = dataset.postprocess(d) tracks = [] for sample in range(reconstructed.shape[0]): for track in range(reconstructed.shape[1]): t = pproll.Track(pianoroll=reconstructed[sample, track, :, :], program=0) t = t.binarize() tracks.append(t) song = pproll.Multitrack(tracks=tracks, resolution=midi_cfg.resolution) song = song.set_nonzeros(1) pproll.write(multitrack=song, path=os.path.join(cfg.Paths.generated, f"reconstructed{sample}.mid"))
def make_musak(model, starting_notes, length): print("composing...") previous_state = None previous_state_u = None #song composed by taking just the argmax of predited notes at each time setp song = np.asarray(starting_notes) #song composed by including all notes with sigmoid over a certain threshold song_u = np.asarray(starting_notes) note = song[-1] note_u = song[-1] threshold = 0.8 volume = 60 print('length', length) for i in range(length+1): logits, previous_state = model.call(np.expand_dims(song[-50: -1], axis=0), previous_state) logits_u, previous_state_u = model.call(np.expand_dims(song_u[-50: -1], axis=0), previous_state_u) choice = np.argmax(logits[-1][0].numpy()) note = np.zeros(model.note_range) note[choice] = volume note_u = np.where(logits_u[-1][0] > threshold, volume, 0) song = np.append(song, [note], axis = 0) song_u = np.append(song_u, [note_u], axis = 0) song = song[-len(starting_notes):-1] song_u = song_u[-len(starting_notes):-1] print("song", song.shape) print(song) t = pypianoroll.Track(song) multi_1 = pypianoroll.Multitrack(name="song", tracks = [t], beat_resolution=4) multi_1.write('./song.mid') t = pypianoroll.Track(song_u) multi_2 = pypianoroll.Multitrack(name="song", tracks = [t], beat_resolution=4) multi_2.write('./song_u.mid') fig, ax = multi_1.plot() plt.show() fig, ax = multi_2.plot() plt.show()
def pro_chordlabel_to_midi(chord_label, chord_dict, inv_beat_resolution=2, constant_tempo=120): VOL = 90 beat_reol_pnrl = 48 step_width = beat_reol_pnrl * inv_beat_resolution chord_pnrl = np.zeros( (len(chord_label) * beat_reol_pnrl * inv_beat_resolution, 128)) for idx_label, i_label in enumerate(chord_label): midi_chord = chord_dict[chord_dict["Label"] == i_label]['Midi'].values[0] if (idx_label % 2) == 0 and (idx_label + 1 < len(chord_label)): if (chord_label[idx_label] == chord_label[idx_label + 1]): step_end = step_width else: step_end = step_width - 1 else: step_end = step_width - 1 for i_midi_chord in midi_chord: for i in range(0, step_end): chord_pnrl[int(idx_label * step_width + i)][int(i_midi_chord)] = VOL mt = pypianoroll.Multitrack( tracks=[pypianoroll.Track(pianoroll=chord_pnrl)], beat_resolution=beat_reol_pnrl) return mt.to_pretty_midi(constant_tempo=constant_tempo, constant_velocity=60)
def generate_multitrack(pianoroll, instruments, lowest_pitch, n_pitches, beat_resolution): instruments = [Instruments[inst.upper()] for inst in instruments] tempo = 120.0 downbeat = None pianoroll = pianoroll.astype(np.uint8) assert (np.all(np.logical_and(pianoroll >= 0, pianoroll < 128))) full_pitch_pianoroll = np.zeros( (pianoroll.shape[0], pianoroll.shape[1], 128)) full_pitch_pianoroll[:, :, lowest_pitch:lowest_pitch + n_pitches] = pianoroll # create tracks tracks = [] for i, instrument in enumerate(instruments): tracks.append( pp.Track(full_pitch_pianoroll[:, i], is_drum=instrument.is_drum(), program=instrument.midi_program(), name=instrument.name)) # create multitrack piano rolls return pp.Multitrack(tracks=tracks, tempo=tempo * (np.ones(full_pitch_pianoroll.shape[0])), downbeat=downbeat, beat_resolution=beat_resolution, name='generated')
def plot_pianoroll(pianoroll, beat_resolution, fig_name=None): '''Plot a Single Track Pianoroll image :param pianoroll: Pianoroll tensor of shape time_steps * pitches :return: ''' pypianoroll.plot_track(pypianoroll.Track(pianoroll=pianoroll), fig_name, beat_resolution)
def save_music(musics, epoch): multitrack = [] programs = [0, 0, 25, 33, 48] padding = np.zeros((192, 128), dtype=np.uint8) x = [] os.makedirs('Gen_numpy', exist_ok=True) np.save("./Gen_numpy/%d_org.npy" % epoch, musics.cpu().detach().numpy()) for i in range(len(musics[0])): roll_all = np.zeros((0, 128), dtype=np.uint8) for music in musics: roll = music[i] roll = np.reshape(roll.cpu().detach().numpy(), (192, 84)) roll = np.pad(roll, ((0, 0), (24, 20)), 'constant') roll = (roll > 0.5) * 1 roll_all = np.concatenate((roll_all, roll), 0) roll_all = np.concatenate((roll_all, padding), 0) x.append(roll_all) track = pypianoroll.Track(pianoroll=roll_all * 100, program=programs[i], is_drum=i == 0, name='') multitrack.append(track) multitrack = pypianoroll.Multitrack(tracks=multitrack, tempo=120.0, downbeat=[0, 48, 96, 144], beat_resolution=12) os.makedirs('Gen_midi', exist_ok=True) multitrack.write('./Gen_midi/' + str(epoch) + '.mid')
def convert_tensor_to_midi(tensor, tempo, output_file_path): """ Writes a pianoroll tensor to a midi file Parameters ---------- tensor : 2d numpy array pianoroll to be converted to a midi tempo : float tempo to output output_file_path : str output midi file path Returns ------- None """ single_track = pypianoroll.Track(pianoroll=tensor) multi_track = pypianoroll.Multitrack( tracks=[single_track], tempo=tempo, beat_resolution=Constants.beat_resolution) output_file_index = 0 while os.path.isfile(output_file_path.format(output_file_index)): output_file_index += 1 multi_track.write(output_file_path.format(output_file_index))
def to_track(track_np, n=None, is_drum=False, name='piano', program=0): """ If n is given, use the values in N2MIDI/N2NAME and ignore name/program """ if len(track_np.shape) != 3: raise ValueError( "Pass in an array of shape [n_bar, n_timesteps, n_pitches]") n_bar = track_np.shape[0] n_timesteps = track_np.shape[1] tot_timesteps = n_bar * n_timesteps n_pitches = track_np.shape[2] track_np_flat = track_np.reshape(tot_timesteps, -1) padding_amt = (128 - n_pitches) // 2 note_padding = np.zeros((tot_timesteps, padding_amt), dtype=np.bool) track_np_flat = np.concatenate((note_padding, track_np_flat, note_padding), axis=1) if n is not None: program = N2MIDI[n] name = N2NAME[n] is_drum = n == 0 track = ppr.Track(pianoroll=track_np_flat, is_drum=is_drum, name=name, program=program) return track
def save_pianoroll_as_midi( pianoroll, programs=[0, 0, 0, 0], is_drums=[False, False, False, False], tempo=100, # in bpm beat_resolution=4, # number of time steps destination_path=None): pianoroll = pianoroll > 0 # Reshape batched pianoroll array to a single pianoroll array pianoroll_ = pianoroll.reshape( (-1, pianoroll.shape[2], pianoroll.shape[3])) # Create the tracks tracks = [] for idx in range(pianoroll_.shape[2]): tracks.append( pypianoroll.Track(pianoroll_[..., idx], programs[idx], is_drums[idx])) multitrack = pypianoroll.Multitrack(tracks=tracks, tempo=tempo, beat_resolution=beat_resolution) multitrack.write(destination_path) print('Midi saved to ', destination_path) return destination_path
def save(matrix, filename): track = pr.Track(pianoroll=matrix, program=0, is_drum=False, name='classic music transferred from jazz') multitrack = pr.Multitrack(tracks=[track]) pr.utilities.write(multitrack, filename) print("{} saved".format(filename))
def reconstruct(file_path, model, start_bar, end_bar, temperature=0.5, smooth_threshold=0): device = torch.device("cuda" if torch.cuda.is_available() else "cpu") if model.train(): model.eval() with torch.no_grad(): sample_np = getSlicedPianorollMatrixNp(file_path) sample_np = transposeNotesHigherLower(sample_np) sample_np = cutOctaves(sample_np) sample_np = sample_np[start_bar:end_bar] sample = torch.from_numpy(sample_np).float() recon, embed, logvar = model(sample.view(-1, 1, 96, 60).to(device)) recon = torch.softmax(recon, dim=3) recon = recon.squeeze(1).cpu().numpy() # recon /= np.abs(np.max(recon)) recon[recon < (1 - temperature)] = 0 sample_play = debinarizeMidi(sample_np, prediction=False) sample_play = addCuttedOctaves(sample_play) recon = debinarizeMidi(recon, prediction=True) recon = addCuttedOctaves(recon) recon_out = recon[0] sample_out = sample_play[0] if recon.shape[0] > 1: for i in range(recon.shape[0] - 1): sample_out = np.concatenate((sample_out, sample_play[i + 1]), axis=0) recon_out = np.concatenate((recon_out, recon[i + 1]), axis=0) # plot with pypianoroll sample_plot = ppr.Track(sample_out) ppr.plot(sample_plot) recon_plot = ppr.Track(recon_out) ppr.plot(recon_plot) # smooth output smoother = NoteSmoother(recon_out, threshold=smooth_threshold) smoothed_seq = smoother.smooth() smoother_seq_plot = ppr.Track(smoothed_seq) ppr.plot(smoother_seq_plot)
def write_midi(data, filename, low_lim, high_lim, tempo=120.0, br=2): """Save piano roll to a midi file.""" pr = copy.deepcopy(data) pr[pr > 0] = 127 track = pypianoroll.Track(pad_piano_roll(pr, low_lim, high_lim)) multitrack = pypianoroll.Multitrack(tracks=[track], tempo=tempo, beat_resolution=br) multitrack.write(filename)
def save_trim_pianoroll_seq(seq, min_note, max_note, thepath): pypianoroll.Multitrack(tracks=[ pypianoroll.Track( from_trim_pianoroll_to_full( seq, min_note, max_note, )) ], beat_resolution=4).write(thepath)
def visualize_piano_roll(pianoroll_matrix, fs=5): """ input: piano roll matrix with shape (number of notes, time steps) effect: generates a nice graph with the piano roll visualization """ if (pianoroll_matrix.shape[0] == 128): pianoroll_matrix = pianoroll_matrix.T.astype(float) track = pproll.Track(pianoroll=pianoroll_matrix, program=0, is_drum=False, name='piano roll') # Plot the piano-roll fig, ax = track.plot(beat_resolution=fs) plt.show()
def train(self, epochs, train_data, batch_size=128, sample_interval=50): # Load and convert the data #notes = get_notes() #n_vocab = len(set(notes)) #X_train, y_train = prepare_sequences(notes, n_vocab) X_train = train_data # Adversarial ground truths real = np.ones((batch_size, 1)) fake = np.zeros((batch_size, 1)) # Training the model for epoch in range(epochs): # Training the discriminator # Select a random batch of note sequences idx = np.random.randint(0, X_train.shape[0], batch_size) real_seqs = X_train[idx] # noise = np.random.choice(range(484), (batch_size, self.latent_dim)) # noise = (noise-242)/242 noise = np.random.normal( 0, 1, (batch_size, self.seq_length, self.latent_dim)) # Generate a batch of new note sequences gen_seqs = self.generator.predict(noise) # Train the discriminator d_loss_real = self.discriminator.train_on_batch(real_seqs, real) d_loss_fake = self.discriminator.train_on_batch(gen_seqs, fake) d_loss = 0.5 * np.add(d_loss_real, d_loss_fake) # Training the Generator noise = np.random.normal( 0, 1, (batch_size, self.seq_length, self.latent_dim)) # Train the generator (to have the discriminator label samples as real) g_loss = self.combined.train_on_batch(noise, real) # Print the progress and save into loss lists if epoch % sample_interval == 0: print("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100 * d_loss[1], g_loss)) self.disc_loss.append(d_loss[0]) self.gen_loss.append(g_loss) noise = np.random.normal(0, 1, (1, self.seq_length, self.latent_dim)) predictions = self.generator.predict(noise) track = pypianoroll.Track(pianoroll=predictions, program=0, is_drum=False, name='my awesome piano') pypianoroll.write( track, "C:\\Users\\10413\\Desktop\\deep_learning\\project\\midi-lstm-gan-master\\output" )
def _generate_samples(decoder: k.Model): z = np.random.randn(1, 512) predicted = decoder.predict(z) x = dataset.postprocess(predicted) guitar = pproll.Track(pianoroll=predicted[0, :, :], program=0) guitar = guitar.binarize() song = pproll.Multitrack(tracks=[guitar], resolution=midi_cfg.resolution) song = song.set_nonzeros(1) song.validate() pproll.write(multitrack=song, path=os.path.join(cfg.Paths.generated, f"{0}.mid"))
def npy_dg(df,seq_len,bs=8,is_test=False,balance=False,is_tree=False,super_genres=['Pop_Rock','Electronic','Country','RnB','Jazz','Latin','International','Rap','Vocal','New Age','Folk','Reggae','Blues']): while True: batch_all_df = df.sample(n=bs//2).reset_index(drop=True) batch_noprock=noprock.sample(n=bs//2).reset_index(drop=True) xs=list() ys=list() #for batch_df in batch_all_df: x = np.zeros((bs//2,seq_len,128)) if drumz: x_dr = np.zeros((bs/2,seq_len,128)) y = np.zeros((bs//2,len(super_genres))) for i in range(batch_df.shape[0]): try: pi = np.load(_DATA_FOLDER+batch_df['file_id'][i]+'.npy') if drumz: dr = np_file['dr'] except KeyboardInterrupt: sys.exit() except: i-=1 continue if pi.shape[0]<seq_len: x[i,:pi.shape[0]]=pi if drumz: x_dr[i,:pi.shape[0]]=dr else: strt = np.random.randint(pi.shape[0]-seq_len) x[i] = pi[strt:strt+seq_len] if not is_test: transp = np.random.randint(-9,9) tr = pp.Track(pianoroll=x[i]) tr.transpose(transp) x[i] = tr.pianoroll if is_tree: x[i] = du.pianoroll_to_halftree(x[i]) for j in range(len(super_genres)): y[i,j]=batch_df[super_genres[j]][i] x[i] = x[i]/(np.max(x[i],axis=1).reshape((seq_len,1))+10e-7) xs.append(x) ys.append(y) x = np.concatenate(xs,axis=0) y = np.concatenate(ys,axis=0) yield x,y
def pyplot_piano_roll(pr, cmap="Blues", br=None, db=None, low_lim=21, high_lim=109, ax=None): """Plot piano roll representation.""" pr = pad_piano_roll(pr, low_lim, high_lim) pr = pypianoroll.Track(pianoroll=pr) fig, ax = pypianoroll.plot_track(pr, cmap=cmap, beat_resolution=br, downbeats=db) return fig, ax
def merge_tracks(multitrack): # Familia de instrumentos escogidas. trackInfo = (("Drums", 0), ("Bass", 33), ("Brass", 56), ("Piano", 0), ("Ensemble", 48),) tracksToMerge = [[], [], [], [], []] # Observamos a que familia de instrumentos pertenece cada track de la cancion # original. for i, track in enumerate(multitrack.tracks): if track.is_drum: tracksToMerge[0].append(i) elif 32 <= track.program < 40: tracksToMerge[1].append(i) elif 56 <= track.program < 64: tracksToMerge[2].append(i) elif 0 <= track.program < 8: tracksToMerge[3].append(i) elif track.program < 96 or 104 <= track.program < 112: tracksToMerge[4].append(i) tracks = [] # Una vez que asignamos los tracks a mezclarse, los recorremos, mezclandolos. for i, trackList in enumerate(tracksToMerge): # Si hay tracks que se pueden mezclar. if trackList: newTracks = [] for trackIndex in trackList: newTracks.append(multitrack.tracks[trackIndex]) auxM = pypi.Multitrack(tracks=newTracks, tempo=multitrack.tempo, downbeat=multitrack.downbeat, resolution=multitrack.resolution) merged = auxM.blend("max") tracks.append(pypi.Track(pianoroll=merged, program=trackInfo[i][1], is_drum=(i == 0), name=trackInfo[i][0]).standardize().binarize()) # Si no hay tracks, se genera un track vacio. else: tracks.append(pypi.Track(pianoroll=None, program=trackInfo[i][1], is_drum=(i == 0), name=trackInfo[i][0]).standardize().binarize()) # Multitrack con los 5 tracks a utilizar. m = pypi.Multitrack(tracks=tracks, tempo=multitrack.tempo[0], downbeat=multitrack.downbeat, resolution=multitrack.resolution, name=multitrack.name) return m
def create_midi_from_piano_roll( roll: np.ndarray, midi_path: str, lowest_note: str, tempo: int, instrument: int, velocity: float ) -> None: """ Create MIDI file from array with piano roll. :param roll: piano roll :param midi_path: path where resulting MIDI file is going to be saved :param lowest_note: note that corresponds to the lowest row of piano roll :param tempo: number of piano roll's time steps per minute :param instrument: ID (number) of instrument according to General MIDI specification :param velocity: one common velocity for all notes :return: None """ notes_order = { 'C': 0, 'C#': 1, 'D': 2, 'D#': 3, 'E': 4, 'F': 5, 'F#': 6, 'G': 7, 'G#': 8, 'A': 9, 'A#': 10, 'B': 11 } n_semitones_per_octave = 12 n_rows_below = ( n_semitones_per_octave * int(lowest_note[-1]) + notes_order[lowest_note[:-1]] ) n_pypianoroll_pitches = 128 n_rows_above = n_pypianoroll_pitches - n_rows_below - roll.shape[0] resized_roll = np.hstack(( np.zeros((roll.shape[1], n_rows_below)), roll.T, np.zeros((roll.shape[1], n_rows_above)) )) track = pypianoroll.Track(velocity * resized_roll, instrument) multitrack = pypianoroll.Multitrack( tracks=[track], tempo=tempo, beat_resolution=1 ) pypianoroll.write(multitrack, midi_path)
def array2png(roll, filepath): roll = roll.transpose(0, 1, 4, 2, 3) roll = roll.reshape(roll.shape[1], -1, roll.shape[2]) #时间并称1维(t, time, pitch) multiTracks = ppr.Multitrack() for i in range(roll.shape[0]): pianoroll = ((roll[i, :, :] > 0) * 100) #True*100 响度设为100 pianoroll = torch.from_numpy(pianoroll) pad = nn.ZeroPad2d(padding=(0, 128 - pianoroll.shape[1], 0, 0)) pianoroll = pad(pianoroll) pianoroll = pianoroll.numpy() # print("######### show piano roll picture") # print(pianoroll.shape) track = ppr.Track(pianoroll=pianoroll) multiTracks.tracks.append(track) fig, axs = multiTracks.plot() plt.savefig(filepath)
def pianoroll_to_midi(snippet, filename="Sampled/sample.midi"): snippet = np.asarray(snippet, dtype=np.uint8) snippet = snippet * 127 # sets velocity of notes from 1 to 127 (max MIDI velocity) if snippet.shape[1] == 89: snippet = one_hot_pianoroll_to_small_pianoroll(snippet) snippet = small_to_full_pianoroll(snippet) elif snippet.shape[1] == 88: snippet = small_to_full_pianoroll(snippet) else: if not snippet.shape[1] == 128: raise ValueError( "input shape does not have 128 pitches (or 88, then it will be converted automatically) and cannot be converted to MIDI!" ) snippet = ppr.Track(pianoroll=snippet) snippet = ppr.Multitrack(tracks=[snippet], tempo=120, beat_resolution=4) ppr.write(snippet, path_to_root + filename)
def array_to_pypianoroll(array, tempo=60): # Order: Piano, Guitar, Strings, Bass, Drums programs = [ 1, # Accoustic Piano 29, # Electric muted guitar 49, # Orchestral Strings 34, # Electric Bass Finger 118, # DrumSet ] is_drum = [False, False, False, False, True] tracks = [] for track in range(array.shape[0]): tracks.append( pypianoroll.Track(pianoroll=array[track, :, :], program=programs[track], is_drum=is_drum[track])) return pypianoroll.Multitrack(tracks=tracks, tempo=tempo, beat_resolution=96 // 4)
def convert_to_npz(generated_phrase, songs_directory, song_name): padded_phrase = np.pad( generated_phrase, [(0, 0), (0, 0), (LOWEST_NOTE, TOTAL_PIANOROLL_NOTES - LOWEST_NOTE - NUM_NOTES), (0, 0)], 'constant', constant_values=False) #repad notes from 84 to 128 padded_reshaped_phrase = np.reshape( padded_phrase, (NUM_TRACKS, NUM_BARS, BEATS_PER_BAR, TOTAL_PIANOROLL_NOTES)) #reshape to be in pypianoroll format program_list = [0, 0, 24, 32, 48] #list of instruments is_Drum_list = [True, False, False, False, False] name_list = ["Drums", "Piano", "Guitar", "Bass", "Strings"] pianoroll_list = [] for track in range(0, NUM_TRACKS): track_data = padded_reshaped_phrase[track] concated_bars = np.empty((0, TOTAL_PIANOROLL_NOTES), dtype=bool) for bar in range(0, NUM_BARS): concated_bars = np.concatenate((concated_bars, track_data[bar]), axis=0) pianoroll_list.append( pypianoroll.Track(pianoroll=concated_bars, program=program_list[track], is_drum=is_Drum_list[track], name=name_list[track])) multitrack = pypianoroll.Multitrack( tracks=pianoroll_list, tempo=120.0, beat_resolution=24, downbeat=np.asarray([True] + [False] * (NUM_BARS * BEATS_PER_BAR - 1), )) pypianoroll.save(join(songs_directory, (song_name + ".npz")), multitrack)
def pianorollMatrixToTempMidi(matrix, path='../utils/midi_files/temp.mid', prediction=True, show=False, showPlayer=False, autoplay=False): # matrix must be of LENGTHxPITCH dimension here: (96 or more,128) if (prediction): matrix[-3:, :] = 0 tempTrack = ppr.Track(matrix) newTrack = ppr.Multitrack() newTrack.append_track(tempTrack) newTrack.write(path) score = music21.converter.parse(path) if (show): score.show() if (showPlayer): score.show('midi') if (autoplay): music21.midi.realtime.StreamPlayer(score).play()
def numpy_to_pianoroll(folder): #Bass Drums Guitar Piano Strings programs = [34,0,30,1,51] names = ['Bass' ,'Drums' ,'Guitar' ,'Piano' ,'Strings'] tempo = np.full((96), 105) for filename in os.listdir(folder): multisample = np.load(os.path.join(folder,filename)) for sample,i in zip(multisample,range(multisample.shape[0])): tracks = [] classes = [] for instrument,program,name in zip(sample,programs,names): print(instrument.shape) track = np.vstack(instrument) print(track.shape) track[track > 0.5] = 100 track[track < 0.5] = 0 print(track.shape) track = np.pad(track.astype(int),((0,0),(0,44)),mode='constant') if name !='Guitar': print(ppr.metrics.qualified_note_rate((track),2)) print(ppr.metrics.n_pitches_used((track))) classes.append(ppr.metrics.n_pitches_used((track))) print(track.shape) isdrum = False if program == 0: isdrum = True ppr_track = ppr.Track(track,program,isdrum,name) tracks.append(ppr_track) ppr_song = ppr.Multitrack(tracks=tracks, tempo=tempo, beat_resolution=24) for instrument, clasnum in zip(names,classes): print(instrument+':'+str(clasnum)) print(123) plot = ppr.plot_multitrack(ppr_song,mode='separate',ytick='off') plt.savefig('gen_samples/'+filename+str(i)+".png",dpi=400) ppr.write(ppr_song, 'gen_samples/'+filename+"song")
def save_pianoroll(filename, pianoroll, programs, is_drums, tempo, beat_resolution, lowest_pitch): """Saves a batched pianoroll array to a npz file.""" if not np.issubdtype(pianoroll.dtype, np.bool_): raise TypeError("Input pianoroll array must have a boolean dtype.") if pianoroll.ndim != 5: raise ValueError("Input pianoroll array must have 5 dimensions.") if pianoroll.shape[-1] != len(programs): raise ValueError("Length of `programs` does not match the number of " "tracks for the input array.") if pianoroll.shape[-1] != len(is_drums): raise ValueError("Length of `is_drums` does not match the number of " "tracks for the input array.") reshaped = pianoroll.reshape( -1, pianoroll.shape[1] * pianoroll.shape[2], pianoroll.shape[3], pianoroll.shape[4]) # Pad to the correct pitch range and add silence between phrases to_pad_pitch_high = 128 - lowest_pitch - pianoroll.shape[3] padded = np.pad( reshaped, ((0, 0), (0, pianoroll.shape[2]), (lowest_pitch, to_pad_pitch_high), (0, 0)), 'constant') # Reshape the batched pianoroll array to a single pianoroll array pianoroll_ = padded.reshape(-1, padded.shape[2], padded.shape[3]) print("pianoroll_", np.shape(pianoroll_)) # Create the tracks tracks = [] for idx in range(pianoroll_.shape[2]): tracks.append(pypianoroll.Track( pianoroll_[..., idx], programs[idx], is_drums[idx])) # Create and save the multitrack multitrack = pypianoroll.Multitrack( tracks=tracks, tempo=tempo, beat_resolution=beat_resolution) multitrack.save(filename)
def main(mono_files, comparison_dir): np.random.shuffle(mono_files) found = 0 with tqdm(total=100) as progress: for f in mono_files: midi = pypianoroll.Multitrack(f, beat_resolution=4) roll = midi.tracks[0].pianoroll # 64 = 4 bars, each bar at 16 timesteps each (4 * 4 (beat_resolution)) roll = roll[:64] notes_in_roll = np.argmax(roll, axis=1) notes_non_zero = len(notes_in_roll[np.where(notes_in_roll != 0)]) # minimum 30% rate = notes_non_zero / 64 if rate >= .3: new_midi = pypianoroll.Multitrack( tracks=[pypianoroll.Track(roll)], beat_resolution=4) unique_name = f.split(os.path.sep)[-1] new_midi.write(os.path.join(comparison_dir, unique_name)) found += 1 progress.update(1) if found == 100: return
import tqdm import numpy as np from glob import glob import os from matplotlib import pyplot as plt from my_encoder import encoder import pypianoroll DATASET_LOC = os.path.abspath("D:\\data\\folkdataset\\") DATASET_GLOB = os.path.join(DATASET_LOC, "*.mid") DATASET_FILES = glob(DATASET_GLOB) NEW_LOCATION = os.path.abspath("D:\\data\\folkmagenta\\") files = 200 DATASET_FILES = DATASET_FILES[:files] lens = [] for fname in tqdm.tqdm(DATASET_FILES): one_bar = pypianoroll.Multitrack(fname).tracks[0].pianoroll[:96] midi_one_bar = pypianoroll.Multitrack(tracks=[pypianoroll.Track(one_bar)]) midi_one_bar.write('test.mid') seq = encoder.encode('test.mid') lens.append(len(seq)) print(np.mean(lens), np.std(lens)) print(np.quantile(lens, 0.75)) # 24 plt.hist(lens) plt.show()
def main(): pre_melody = pypianoroll.load(args.input) pre = [] step = pre_melody.beat_resolution // 4 # 16 beat minimum pianoroll = np.zeros((pre_melody.get_max_length(),128,len(programs))) for track in pre_melody.tracks: if track.is_drum: dst_index = 0 else: dst_index = 1 for i in range(1,len(programs),1): if track.program >= programs[i] and (len(programs) == i+1 or track.program < programs[i+1]): dst_index = i break pianoroll[0:track.pianoroll.shape[0],:,dst_index] += track.pianoroll pianoroll = pianoroll[:,note_offset:note_offset+note_size,trc_idx] p = np.where(pianoroll != 0) current_seq = [] def _current(cur_seq): cur = [] for c in sorted(cur_seq): if not (c >= note_size and c < note_size*2): cur.append(c) for c in sorted(cur_seq): if (c >= note_size and c < note_size*2): cur.append(c) return cur # Bass, Piano, etc..., Drums pos = 0 for i in np.argsort(p[0]): if p[0][i] % step != 0: continue if pos < p[0][i]: for _ in range(pos,p[0][i],step): pre.extend(_current(current_seq)) pre.append(time_note) current_seq = [] pos = p[0][i] j = p[1][i] t = p[2][i] note = t*note_size + j current_seq.append(note) pre.extend(_current(current_seq)) if len(pre) == 0 or pre[-1] != time_note: pre.append(time_note) if len(pre) > 512: pre = pre[-512:] cur_top = (0,top_p) with tf.Session(graph=tf.Graph()) as sess: context = tf.placeholder(tf.int32, [1, None]) output = model.model(hparams=hparams, X=context) vars = [v for v in tf.trainable_variables() if 'model' in v.name] saver = tf.train.Saver(var_list=vars) ckpt = tf.train.latest_checkpoint(args.model) saver.restore(sess, ckpt) pianoroll = np.zeros((trc_len, args.num_bars*16, 128)) seq = get_sequence(sess, context, pre, cur_top) pos = 0 firstnote = False print('Generating Melody...') progress = tqdm(total=pianoroll.shape[1]) while pos < pianoroll.shape[1]: for note in seq: if (not firstnote) and note >= time_note: continue else: firstnote = True pre.append(note) if note == time_note: pos += 1 progress.update(1) if pos >= pianoroll.shape[1]: break elif note < time_note: trc = trc_idx.index(note // note_size) mid = note % note_size + note_offset if mid < 128: pianoroll[trc,pos,mid] = 100 seq = get_sequence(sess, context, pre[-512:], cur_top) pr = [] for i,(t,p) in enumerate(zip(tracks,programs)): pr.append(pypianoroll.Track(pianoroll=pianoroll[i], program=p, is_drum=(t=='Drums'))) mt = pypianoroll.Multitrack(tracks=pr, tempo=args.tempo, beat_resolution=4) mt.write(args.output)