def testSimpleSequenceToPrettyMidi_FirstTempoNotAtZero(self): source_midi = pretty_midi.PrettyMIDI(self.midi_simple_filename) multi_tempo_sequence_proto = midi_io.midi_to_sequence_proto( source_midi) del multi_tempo_sequence_proto.tempos[:] multi_tempo_sequence_proto.tempos.add(time=1.0, qpm=60) multi_tempo_sequence_proto.tempos.add(time=2.0, qpm=120) translated_midi = midi_io.sequence_proto_to_pretty_midi( multi_tempo_sequence_proto) # Translating to MIDI adds an implicit DEFAULT_QUARTERS_PER_MINUTE tempo # at time 0, so recreate the list with that in place. del multi_tempo_sequence_proto.tempos[:] multi_tempo_sequence_proto.tempos.add( time=0.0, qpm=constants.DEFAULT_QUARTERS_PER_MINUTE) multi_tempo_sequence_proto.tempos.add(time=1.0, qpm=60) multi_tempo_sequence_proto.tempos.add(time=2.0, qpm=120) self.CheckPrettyMidiAndSequence(translated_midi, multi_tempo_sequence_proto)
def testInstrumentInfo_NoteSequenceToPrettyMidi(self): source_sequence = music_pb2.NoteSequence() source_sequence.notes.add( pitch=60, start_time=0.0, end_time=0.5, velocity=80, instrument=0) source_sequence.notes.add( pitch=60, start_time=0.5, end_time=1.0, velocity=80, instrument=1) instrument_info1 = source_sequence.instrument_infos.add() instrument_info1.name = 'inst_0' instrument_info1.instrument = 0 instrument_info2 = source_sequence.instrument_infos.add() instrument_info2.name = 'inst_1' instrument_info2.instrument = 1 translated_midi = midi_io.sequence_proto_to_pretty_midi(source_sequence) translated_sequence = midi_io.midi_to_note_sequence(translated_midi) self.assertEqual( len(source_sequence.instrument_infos), len(translated_sequence.instrument_infos)) self.assertEqual(source_sequence.instrument_infos[0].name, translated_sequence.instrument_infos[0].name) self.assertEqual(source_sequence.instrument_infos[1].name, translated_sequence.instrument_infos[1].name)
def split_on_downbeats(sequence, bars_per_segment, downbeats=None, skip_bars=0, min_notes_per_segment=0, include_span=False): if downbeats is None: downbeats = midi_io.sequence_proto_to_pretty_midi( sequence).get_downbeats() downbeats = [d for d in downbeats if d < sequence.total_time] try: iter(bars_per_segment) except TypeError: bars_per_segment = [bars_per_segment] for bps in bars_per_segment: first_split = skip_bars or bps # Do not split at time 0 split_times = list(downbeats[first_split::bps]) segments = sequences_lib.split_note_sequence( sequence, hop_size_seconds=split_times) if skip_bars: # The first segment will contain the bars we want to skip segments.pop(0) for i, segment in enumerate(segments): start = skip_bars + i * bps end = start + bps if len(segment.notes) < min_notes_per_segment: print( f'Skipping segment {start}-{end} with {len(segment.notes)} notes', file=sys.stderr) continue if include_span: yield start, end, segment else: yield segment
def CheckSequenceToPrettyMidi(self, filename): """Test the translation from Sequence proto to PrettyMIDI.""" source_midi = pretty_midi.PrettyMIDI(filename) sequence_proto = midi_io.midi_to_sequence_proto(source_midi) translated_midi = midi_io.sequence_proto_to_pretty_midi(sequence_proto) self.CheckPrettyMidiAndSequence(translated_midi, sequence_proto)
def get_downbeats(sequence): downbeats = midi_io.sequence_proto_to_pretty_midi(sequence).get_downbeats() return [d for d in downbeats if d < sequence.total_time]