def write_midi(filepath, pianorolls, config): is_drums = config['is_drums'] track_names = config['track_names'] tempo = config['tempo'] beat_resolution = config['beat_resolution'] program_nums = config['program_nums'] 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 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 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 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_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} multi = Multitrack(tempo=multitrack.tempo, downbeat=multitrack.downbeat, beat_resolution=multitrack.beat_resolution, name=multitrack.name) 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) for key in category_list.keys(): is_drum = key == 'Drums' if category_list[key]: merged = multitrack[category_list[key]].get_merged_pianoroll() track = Track(merged, program_dict[key], is_drum=is_drum, name=key) # track.plot() multi.append_track(track) else: track = Track(None, program_dict[key], is_drum=is_drum, name=key) multi.append_track(track) return multi
def drawPianoRoll(pianoroll, title=''): # Create a `pypianoroll.Track` instance pianoroll = pianoroll.T track = Track(pianoroll=pianoroll, program=0, is_drum=False, name=title) # Plot the piano-roll fig, ax = track.plot() plt.show()
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 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 make_mid(data, threshold): tarck1 = data[0][:,:,0] tarck2 = data[0][:,:,1] tarck1 = tarck1 >= threshold tarck2 = tarck2 >= threshold print(tarck1) print(tarck2) print("num of non-zero :",np.sum(tarck1)+np.sum(tarck2)) tarck1 = Track(tarck1, program=0, is_drum=False, name='unknown') tarck2 = Track(tarck2, program=0, is_drum=False, name='unknown') return tarck1,tarck2
def save_midi(file_path, stacked_piano_rolls, program_nums=None, is_drums=None, track_names=None, tempo=80.0, beat_resolution=24): """ Write the given piano-roll(s) to a single MIDI file. :param file_path: :param stacked_piano_rolls: np.ndarray, shape=(num_time_step, 128, num_track) :param program_nums: :param is_drums: :param track_names: :param tempo: :param beat_resolution: :return: """ # Check arguments # if not np.issubdtype(stacked_piano_rolls.dtype, np.bool_): # raise TypeError("Support only binary-valued piano-rolls") if stacked_piano_rolls.shape[2] != len(program_nums): raise ValueError( "`stacked_piano_rolls.shape[2]` and `program_nums` must have be the same" ) if stacked_piano_rolls.shape[2] != len(is_drums): raise ValueError( "`stacked_piano_rolls.shape[2]` and `is_drums` must have be the same" ) if isinstance(program_nums, int): program_nums = [program_nums] if isinstance(is_drums, int): is_drums = [is_drums] if program_nums is None: program_nums = [0] * len(stacked_piano_rolls) if is_drums is None: is_drums = [False] * len(stacked_piano_rolls) # Write midi multitrack = Multitrack(tempo=tempo, beat_resolution=beat_resolution) for idx in range(stacked_piano_rolls.shape[2]): if track_names is None: track = Track(stacked_piano_rolls[..., idx], program_nums[idx], is_drums[idx]) else: track = Track(stacked_piano_rolls[..., idx], program_nums[idx], is_drums[idx], track_names[idx]) multitrack.append_track(track) multitrack.write(file_path)
def process_harmonization(midi_filename, nets, global_lower, real_tracks, voice_togenerate, start_size): """ Generate voice from a given soprano voice as a track object :midi_filename: :nets: networks list from which the voices are generated :global_lower: minimal pitch among all voices :real_tracks: list of real voices :voice_togenerate: voice that we want to generate (1,2,3) :start_size: imposed size of real voice at the start of the generated voice :return: track object of the generated voice """ soprano_pianoroll = scale_pianoroll( flatten_one_hot_pianoroll(real_tracks[0].pianoroll), global_lower) pianoroll_real = scale_pianoroll( flatten_one_hot_pianoroll(real_tracks[voice_togenerate].pianoroll), global_lower) # predict the second voice pianoroll = sample_harmonization(nets[voice_togenerate], soprano_pianoroll, prime=pianoroll_real[:start_size]) # go back to the pitch range pianoroll = unscale_pianoroll(pianoroll, global_lower) # convert to one-hot representation for track object one_hot = one_hot_encode_pianoroll(pianoroll, 128) * 80 # get the track object track = Track(pianoroll=one_hot, name='generated track') return track
def plot_track(track, cmap='Blues', single=True, bres=3): t = track if t.shape[1] != 128: t = np.append(np.zeros(((t.shape[0]), 34)), t, axis=1) t = np.append(t, np.zeros((t.shape[0], 47)), axis=1) pr = Track(pianoroll=t) fig, axs = pr.plot(xtick='beat', ytick='octave', yticklabel='number', beat_resolution=bres, cmap=cmap) y = axs.set_ylim(34, 81) # C0 - C2 if single: x = axs.set_xlim(0, BAR_DIVISION) plt.show()
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 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 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 generate_pianoroll_from_progression(prog, num_chords, duration): pianoroll = np.zeros((num_chords * duration, 128)) # C_maj = [60, 64, 67, 72, 76, 79, 84] # pianoroll[0:95, C_maj] = 100 vel = 100 gap_size = 12 spread = 4.0 # def sample_notes(n): return np.random.choice(n, rand_octave_shift(3) + 1) def sample_notes(n): return n # identity sample for idx, chord in enumerate(prog.chords): OCTAVE = 4 notes = [(OCTAVE + rand_octave_shift(spread)) * 12 + NOTE_TO_INT[c] for c in chord.components()] # sampled_notes = np.random.choice(notes, rand_octave_shift(3)) sampled_notes = sample_notes(notes) print(chord, chord.components(), notes, sampled_notes) left_offset = idx * duration right_offset = left_offset + duration - gap_size pianoroll[left_offset:right_offset, sampled_notes] = vel track = Track(pianoroll=pianoroll, program=0, is_drum=False, name='my awesome piano') return track
def pltReducedDrumTrack(track, beat_resolution=12, cmap='Blues'): track = np.append(track, np.zeros((track.shape[0], 119)), axis=1) # track = np.where(track == 1, 128, 0) track = track * 128 track = Track(pianoroll=track) fig, axs = track.plot( xtick='beat', yticklabel='number', beat_resolution=beat_resolution, cmap=cmap, ) fig.set_size_inches(30,10) y = axs.set_ylim(0, 10) # C0 - C2 y = axs.set_yticks(range(10)) plt.show()
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 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 write_pianoroll(result_dir, melody_data, accompany_pianoroll_frame, chord_groundtruth_frame, length, tempos, downbeats): print('write pianoroll...') if not os.path.exists(result_dir): os.makedirs(result_dir) counter = 0 for melody_roll, chord_roll, truth_roll, l, tempo, downbeat in tqdm( zip(melody_data, accompany_pianoroll_frame, chord_groundtruth_frame, length, tempos, downbeats), total=len(melody_data)): melody_roll, chord_roll, truth_roll = melody_roll[: l], chord_roll[: l], truth_roll[: l] track1 = Track(pianoroll=melody_roll) track2 = Track(pianoroll=chord_roll) track3 = Track(pianoroll=truth_roll) generate = Multitrack(tracks=[track1, track2], tempo=tempo, downbeat=downbeat, beat_resolution=Constants.BEAT_RESOLUTION) truth = Multitrack(tracks=[track1, track3], tempo=tempo, downbeat=downbeat, beat_resolution=Constants.BEAT_RESOLUTION) pr.write(generate, result_dir + '/generate_' + str(counter) + '.mid') pr.write(truth, result_dir + '/groundtruth_' + str(counter) + '.mid') fig, axs = generate.plot() plt.savefig(result_dir + '/generate_' + str(counter) + '.png') plt.close() fig, axs = truth.plot() plt.savefig(result_dir + '/groundtruth_' + str(counter) + '.png') plt.close() counter += 1 print('Finished!')
def test(): tmp_pypianoroll = Multitrack("./mz_545_1.mid") print(tmp_pypianoroll.tracks[0]) tmp_pypianoroll.remove_empty_tracks() tmp_np = tmp_pypianoroll.get_stacked_pianoroll() tarck1 = tmp_np[:960,:,0] tarck2 = tmp_np[:960,:,1] tarck1 = tarck1 > 0.1 tarck2 = tarck2 > 0.1 tarck1 = Track(tarck1, program=0, is_drum=False, name='unknown') tarck2 = Track(tarck2, program=0, is_drum=False, name='unknown') cc = Multitrack(tracks=[tarck1,tarck2], tempo=120.0,beat_resolution=24) #print(cc) cc.write('test_2.mid')
def write_midi(filepath, pianorolls, program_nums=None, is_drums=None, track_names=None, velocity=100, tempo=162.0, beat_resolution=16): # if not os.path.exists(filepath): # os.makedirs(filepath) 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]): # plt.subplot(10,1,idx+1) # plt.imshow(pianorolls[..., idx].T,cmap=plt.cm.binary, interpolation='nearest', aspect='auto') 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) # plt.savefig(cf.MP3Name) multitrack.write(filepath)
def get_multitrack(self): """ Returns the pypianoroll Multitrack representation of the midi created from the pianoroll array. This track has one piano track with an assumed tempo of 120 and a beat resolution of 24. """ track = Track(pianoroll=self.array, program=0, is_drum=False) return Multitrack(tracks=[track], tempo=120, downbeat=None, beat_resolution=24)
def make_chord_track(chord, instrument, volume=40): pianoroll = np.zeros((128, 128)) for i in range(len(chord)): st = 16 * i ed = st + 16 chord_pitch = chord[i] pianoroll[st:ed, chord_pitch] = volume track = Track(pianoroll=pianoroll, program=instrument, is_drum=False, name='chord') return track
def pianoroll_to_multitrack(stacked_pianorolls, program_nums=None, is_drums=None, track_names=None, tempo=80.0, beat_resolution=24): """ Convert the given piano-roll(s) to a Multitrack object. :param file_path: :param stacked_pianorolls: np.ndarray, shape=(num_time_step, 128, num_track) :param program_nums: :param is_drums: :param track_names: :param tempo: :param beat_resolution: :return: """ # Check arguments if not np.issubdtype(stacked_pianorolls.dtype, np.bool_): raise TypeError("Support only binary-valued piano-rolls") if stacked_pianorolls.shape[2] != len(program_nums): raise ValueError("`stacked_piano_rolls.shape[2]` and `program_nums` must have be the same") if stacked_pianorolls.shape[2] != len(is_drums): raise ValueError("`stacked_piano_rolls.shape[2]` and `is_drums` must have be the same") if isinstance(program_nums, int): program_nums = [program_nums] if isinstance(is_drums, int): is_drums = [is_drums] if program_nums is None: program_nums = [0] * len(stacked_pianorolls) if is_drums is None: is_drums = [False] * len(stacked_pianorolls) # Save as a Multitrack tracks = list() for idx in range(stacked_pianorolls.shape[2]): if track_names is None: track = Track(stacked_pianorolls[..., idx], program_nums[idx], is_drums[idx]) else: track = Track(stacked_pianorolls[..., idx], program_nums[idx], is_drums[idx], track_names[idx]) tracks.append(track) return Multitrack(tracks=tracks, tempo=tempo, beat_resolution=beat_resolution)
def train(epoch): model.train() train_loss = 0 for batch_index, data in enumerate(train_loader): optimizer.zero_grad() recon, mu, log_var = model(data) loss = loss_function(recon, data, mu, log_var) loss.backward(retain_graph=True) # loss.backward() train_loss += loss.item() optimizer.step() if batch_index % 1 == 0: print 'Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch, batch_index * len(data), len(train_loader.dataset), 100. * batch_index / len(train_loader), loss.item() / len(data)) sample = recon[0].detach().numpy() sample = np.repeat(sample, 6, axis=0) track = Track(pianoroll=sample) track.binarize(0.2) track = pypianoroll.Multitrack(tracks=[track], tempo=120) track.write('sample/sample_%d.mid' % (batch_index)) print '-----------------------------' print 'Epoch: {} Average Loss: {:.4f}'.format( epoch, train_loss / len(train_loader.dataset))
def _merge(multitrack): """Return a `pypianoroll.Multitrack` instance with piano-rolls merged to four tracks (Bass, Guitar, Piano and Strings)""" category_list = {'Piano': [], 'Guitar': [], 'Bass': [], 'Strings': []} program_dict = {i.name: i.value for i in Instrument} #cf) program: 0 to 127 for idx, track in enumerate(multitrack.tracks): if track.is_drum: pass elif track.program // 8 == 0: #0 - 7 category_list['Piano'].append(idx) elif track.program // 8 == 3: #24 - 31 category_list['Guitar'].append(idx) elif track.program // 8 == 4: #32 - 39 category_list['Bass'].append(idx) elif track.program // 8 == 5: #40 - 47 category_list['Strings'].append(idx) else: category_list['Strings'].append(idx) pass tracks = [] for key, index_list in category_list.items(): if index_list: merged = multitrack[index_list].get_merged_pianoroll() tracks.append( Track(pianoroll=merged, program=program_dict[key], is_drum=False, name=key)) else: tracks.append( Track(pianoroll=None, program=program_dict[key], is_drum=False, name=key)) return Multitrack(None, tracks, multitrack.tempo, multitrack.downbeat, multitrack.beat_resolution, multitrack.name)
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 = Track(pianoroll=self.pianoroll, program=0, is_drum=False, name=self.name) tempMulti = proll(tracks=(tempTrack,), beat_resolution=self.quantization) tempMulti.write(midiPath)
def write_one_pianoroll(result_dir, filename, melody_data, accompany_pianoroll_frame, chord_groundtruth_frame, length, tempo, downbeat): print('write pianoroll...') if not os.path.exists(result_dir): os.makedirs(result_dir) l = length melody_roll, chord_roll, truth_roll = melody_data[ 0][:l], accompany_pianoroll_frame[0][:l], chord_groundtruth_frame[ 0][:l] track1 = Track(pianoroll=melody_roll) track2 = Track(pianoroll=chord_roll) track3 = Track(pianoroll=truth_roll) generate = Multitrack(tracks=[track1, track2], tempo=tempo[0], downbeat=downbeat[0], beat_resolution=Constants.BEAT_RESOLUTION) truth = Multitrack(tracks=[track1, track3], tempo=tempo[0], downbeat=downbeat[0], beat_resolution=Constants.BEAT_RESOLUTION) pr.write(generate, result_dir + '/generate-' + filename + '.mid') pr.write(truth, result_dir + '/groundtruth-' + filename + '.mid') fig, axs = generate.plot() plt.savefig(result_dir + '/generate-' + filename + '.png') plt.close() fig, axs = truth.plot() plt.savefig(result_dir + '/groundtruth-' + filename + '.png') plt.close() print('Finished!')
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 generate_track_from_numpy_matrix(self, path, size, name, is_drum, save_fig=False, save_path=None, program=0): piano_roll = np.load(path) piano_roll.resize(size) track = Track(piano_roll, program, is_drum, name) fig, ax = pypianoroll.track.plot_track(track) if save_fig: plt.savefig(save_path) else: plt.show()