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)
Beispiel #2
0
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
Beispiel #5
0
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)
Beispiel #6
0
    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))
Beispiel #7
0
 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)
Beispiel #10
0
    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'))
Beispiel #11
0
    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)
Beispiel #12
0
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)
Beispiel #13
0
 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)
Beispiel #14
0
    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
Beispiel #15
0
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)
Beispiel #18
0
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
Beispiel #19
0
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)
Beispiel #20
0
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
Beispiel #22
0
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)
Beispiel #23
0
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
Beispiel #24
0
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,
    )
Beispiel #25
0
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)
Beispiel #26
0
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
Beispiel #29
0
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)
Beispiel #30
0
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()

    '''
Beispiel #32
0
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