def occupation_polyphony_rate(pm: PrettyMIDI) -> Tuple[ndarray, ndarray]: occupation_rate = [] polyphony_rate = [] total_roll = pm.get_piano_roll() for instrument in pm.instruments: piano_roll = instrument.get_piano_roll() if piano_roll.shape[1] == 0: occupation_rate.append(0) else: occupation_rate.append( np.count_nonzero(np.any(piano_roll, 0)) / total_roll.shape[1]) if np.count_nonzero(np.any(piano_roll, 0)) == 0: polyphony_rate.append(0) else: polyphony_rate.append( np.count_nonzero(np.count_nonzero(piano_roll, 0) > 1) / np.count_nonzero(np.any(piano_roll, 0))) occupation_rate = np.array(occupation_rate) zero_idx = np.where(occupation_rate < 0.01)[0] if len(zero_idx) > 0: occupation_rate[zero_idx] = 0 occupation_rate = occupation_rate[:, np.newaxis] polyphony_rate = np.array(polyphony_rate) zero_idx = np.where(polyphony_rate < 0.01)[0] if len(zero_idx) > 0: polyphony_rate[zero_idx] = 0 polyphony_rate = polyphony_rate[:, np.newaxis] return occupation_rate, polyphony_rate
def load_melody_roll(self, midi_path, melody_track): """ TODO: for each midi file, label which track index is the melody For now, assume that we somehow know which track is the melody """ self.midi_path = midi_path self.midi_name = midi_path.split(sep='/')[-1] mid = MidiFile(midi_path) # for i, track in enumerate(mid.tracks): # print("Track {}: {}".format(i, track.name)) melody = mid.tracks[melody_track] # drop all tracks except for melody mid.tracks = [melody] mid.save(PREPROCESS_MIDI_DIR + self.midi_name) # now we have a midi file with only the melody track # use Pretty Midi to extract the piano roll into a 2d numpy array # roll = (PITCH_SPACE x ROLL_LENGTH) midi_data = PrettyMIDI(PREPROCESS_MIDI_DIR + self.midi_name) # get the instrument of the midi, should only be one melody track! assert len(midi_data.instruments) == 1 print("instrument", midi_data.instruments) self.program = midi_data.instruments[0].program self.roll = midi_data.get_piano_roll(fs=400)
def get_piano_roll(pm: PrettyMIDI, beat_times: ndarray) -> PianoRoll: piano_roll = pm.get_piano_roll(times=beat_times) np.nan_to_num(piano_roll, copy=False) piano_roll = piano_roll > 0 piano_roll = piano_roll.astype(int) return piano_roll