def testSplitNoteSequenceDuplicateTimeChanges(self): # Tests splitting a NoteSequence on time changes for a NoteSequence that has # duplicate time changes. sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence( sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence( sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence = music_pb2.NoteSequence() expected_subsequence.CopyFrom(sequence) expected_subsequence.subsequence_info.start_time_offset = 0.0 expected_subsequence.subsequence_info.end_time_offset = 0.0 subsequences = sequences_lib.split_note_sequence_on_time_changes(sequence) self.assertEquals(1, len(subsequences)) self.assertProtoEquals(expected_subsequence, subsequences[0])
def testSplitNoteSequenceCoincidentTimeChanges(self): sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 3 denominator: 4} tempos: { qpm: 60} tempos: { time: 2.0 qpm: 80}""") testing_lib.add_track_to_sequence( sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence( sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence_1 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence( expected_subsequence_1, 0, [(12, 100, 0.01, 2.0), (11, 55, 0.22, 0.50)]) testing_lib.add_chords_to_sequence( expected_subsequence_1, [('C', 1.5)]) expected_subsequence_1.total_time = 2.0 expected_subsequence_1.subsequence_info.end_time_offset = 8.0 expected_subsequence_2 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 3 denominator: 4} tempos: { qpm: 80}""") testing_lib.add_track_to_sequence( expected_subsequence_2, 0, [(40, 45, 0.50, 1.50), (55, 120, 2.0, 2.01), (52, 99, 2.75, 3.0)]) testing_lib.add_chords_to_sequence( expected_subsequence_2, [('C', 0.0), ('G7', 1.0), ('F', 2.8)]) expected_subsequence_2.total_time = 3.0 expected_subsequence_2.subsequence_info.start_time_offset = 2.0 expected_subsequence_2.subsequence_info.end_time_offset = 5.0 subsequences = sequences_lib.split_note_sequence_on_time_changes(sequence) self.assertEquals(2, len(subsequences)) self.assertProtoEquals(expected_subsequence_1, subsequences[0]) self.assertProtoEquals(expected_subsequence_2, subsequences[1])
def magent_melody_extractor(midi_path, max_bars=100): data_converter = music_vae_data.OneHotMelodyConverter( valid_programs=music_vae_data.MEL_PROGRAMS, skip_polyphony=False, max_bars=max_bars, # Truncate long melodies before slicing. slice_bars=16, steps_per_quarter=4) ns = convert_midi("", '', midi_path) all_melodies = [] try: note_sequences = sequences_lib.split_note_sequence_on_time_changes(ns) for ns in note_sequences: # filter notes -------------------------------------------------------- def filter(note): if (data_converter._valid_programs is not None and note.program not in data_converter._valid_programs): return False return data_converter._min_pitch <= note.pitch <= data_converter._max_pitch notes = list(ns.notes) del ns.notes[:] ns.notes.extend([n for n in notes if filter(n)]) # quantize sequence --------------------------------------------------- quantized_sequence = mm.quantize_note_sequence( ns, data_converter._steps_per_quarter) # extract melodies ---------------------------------------------------- melodies, _ = data_converter._event_extractor_fn( quantized_sequence) all_melodies.extend(melodies) except: pass return all_melodies
def testSplitNoteSequenceDuplicateTimeChanges(self): # Tests splitting a NoteSequence on time changes for a NoteSequence that has # duplicate time changes. sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence(sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence(sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence = music_pb2.NoteSequence() expected_subsequence.CopyFrom(sequence) expected_subsequence.subsequence_info.start_time_offset = 0.0 expected_subsequence.subsequence_info.end_time_offset = 0.0 subsequences = sequences_lib.split_note_sequence_on_time_changes( sequence) self.assertEquals(1, len(subsequences)) self.assertProtoEquals(expected_subsequence, subsequences[0])
def testSplitNoteSequenceCoincidentTimeChanges(self): sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 3 denominator: 4} tempos: { qpm: 60} tempos: { time: 2.0 qpm: 80}""") testing_lib.add_track_to_sequence(sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence(sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence_1 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence(expected_subsequence_1, 0, [(12, 100, 0.01, 2.0), (11, 55, 0.22, 0.50)]) testing_lib.add_chords_to_sequence(expected_subsequence_1, [('C', 1.5)]) expected_subsequence_1.total_time = 2.0 expected_subsequence_1.subsequence_info.end_time_offset = 8.0 expected_subsequence_2 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 3 denominator: 4} tempos: { qpm: 80}""") testing_lib.add_track_to_sequence(expected_subsequence_2, 0, [(40, 45, 0.50, 1.50), (55, 120, 2.0, 2.01), (52, 99, 2.75, 3.0)]) testing_lib.add_chords_to_sequence(expected_subsequence_2, [('C', 0.0), ('G7', 1.0), ('F', 2.8)]) expected_subsequence_2.total_time = 8.0 expected_subsequence_2.subsequence_info.start_time_offset = 2.0 subsequences = sequences_lib.split_note_sequence_on_time_changes( sequence) self.assertEquals(2, len(subsequences)) self.assertProtoEquals(expected_subsequence_1, subsequences[0]) self.assertProtoEquals(expected_subsequence_2, subsequences[1])
def preprocess_notesequence(note_sequence, presplit_on_time_changes): """Preprocesses a single NoteSequence, resulting in multiple sequences.""" if presplit_on_time_changes: note_sequences = sequences_lib.split_note_sequence_on_time_changes( note_sequence) else: note_sequences = [note_sequence] return note_sequences
def to_tensors(self, note_sequence): """Python method that converts `note_sequence` into list of tensors.""" if self._presplit_on_time_changes: note_sequences = sequences_lib.split_note_sequence_on_time_changes( note_sequence) else: note_sequences = [note_sequence] results = [] for ns in note_sequences: r = self._to_tensors(ns) if r[0]: results.extend(zip(*r)) sampled_results = self._maybe_sample_outputs(results) return list(zip(*sampled_results)) if sampled_results else ([], [])
def to_tensors(self, note_sequence): """Python method that converts `note_sequence` into list of tensors.""" if self._presplit_on_time_changes: note_sequences = sequences_lib.split_note_sequence_on_time_changes( note_sequence) else: note_sequences = [note_sequence] results = [] for ns in note_sequences: inputs, outputs = self._to_tensors(ns) if inputs: lengths = [len(i) for i in inputs] results.extend(zip(inputs, outputs, lengths)) sampled_results = self._maybe_sample_outputs(results) return tuple(zip(*sampled_results)) if sampled_results else ([], [], [])
def test_split_and_quantize(): for midi_path in common.midi_big_paths: # print(midi_path) ns = convert_midi("", '', midi_path) note_sequences = sequences_lib.split_note_sequence_on_time_changes(ns) pm = pretty_midi.PrettyMIDI(midi_path) nc = NoteContainer.from_pretty_midi(pm) split_ncs = nc_lib.split_on_time_signature_tempo_change(nc) for nc, ns in zip(split_ncs, note_sequences): assert_nc_ns(nc, ns) qnc = nc_lib.quantize_note_container(nc, 4) qns = mm.quantize_note_sequence(ns, 4) assert_nc_ns(qnc, qns, quantized=True)
def testSplitNoteSequenceNoTimeChanges(self): sequence = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence( sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence( sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence = music_pb2.NoteSequence() expected_subsequence.CopyFrom(sequence) expected_subsequence.subsequence_info.start_time_offset = 0.0 expected_subsequence.subsequence_info.end_time_offset = 0.0 subsequences = sequences_lib.split_note_sequence_on_time_changes(sequence) self.assertEquals(1, len(subsequences)) self.assertProtoEquals(expected_subsequence, subsequences[0])
def testTimeChangeSplitter(self): note_sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { time: 2.0 numerator: 3 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence( note_sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) expected_sequences = sequences_lib.split_note_sequence_on_time_changes( note_sequence) unit = note_sequence_pipelines.TimeChangeSplitter() self._unit_transform_test(unit, note_sequence, expected_sequences)
def testSplitNoteSequenceNoTimeChanges(self): sequence = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence(sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence(sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence = music_pb2.NoteSequence() expected_subsequence.CopyFrom(sequence) expected_subsequence.subsequence_info.start_time_offset = 0.0 expected_subsequence.subsequence_info.end_time_offset = 0.0 subsequences = sequences_lib.split_note_sequence_on_time_changes( sequence) self.assertEquals(1, len(subsequences)) self.assertProtoEquals(expected_subsequence, subsequences[0])
def testSplitNoteSequenceMultipleTimeChangesNoSplitNotes(self): sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 3 denominator: 4} tempos: { qpm: 60} tempos: { time: 4.25 qpm: 80}""", ) testing_lib.add_track_to_sequence( sequence, 0, [ (12, 100, 0.01, 3.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0), ], ) testing_lib.add_chords_to_sequence(sequence, [("C", 1.5), ("G7", 3.0), ("F", 4.8)]) expected_subsequence_1 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 3 denominator: 4} tempos: { qpm: 60}""", ) testing_lib.add_track_to_sequence( expected_subsequence_1, 0, [(12, 100, 0.01, 3.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01)], ) testing_lib.add_chords_to_sequence(expected_subsequence_1, [("C", 1.5), ("G7", 3.0)]) expected_subsequence_1.total_time = 4.25 expected_subsequence_1.subsequence_info.end_time_offset = 0.75 expected_subsequence_2 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 3 denominator: 4} tempos: { qpm: 80}""", ) testing_lib.add_track_to_sequence(expected_subsequence_2, 0, [(52, 99, 0.5, 0.75)]) testing_lib.add_chords_to_sequence(expected_subsequence_2, [("G7", 0.0), ("F", 0.55)]) expected_subsequence_2.total_time = 0.75 expected_subsequence_2.subsequence_info.start_time_offset = 4.25 subsequences = sequences_lib.split_note_sequence_on_time_changes(sequence, split_notes=False) self.assertEquals(2, len(subsequences)) self.assertProtoEquals(expected_subsequence_1, subsequences[0]) self.assertProtoEquals(expected_subsequence_2, subsequences[1])
def transform(self, note_sequence): return sequences_lib.split_note_sequence_on_time_changes(note_sequence)
def testSplitNoteSequenceMultipleTimeChanges(self): # Tests splitting a NoteSequence on time changes, truncating notes on splits # that occur inside notes. sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 3 denominator: 4} tempos: { qpm: 60} tempos: { time: 4.25 qpm: 80}""") testing_lib.add_track_to_sequence(sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence(sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence_1 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence(expected_subsequence_1, 0, [(12, 100, 0.01, 2.0), (11, 55, 0.22, 0.50)]) testing_lib.add_chords_to_sequence(expected_subsequence_1, [('C', 1.5)]) expected_subsequence_1.total_time = 2.0 expected_subsequence_1.subsequence_info.end_time_offset = 8.0 expected_subsequence_2 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 3 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence(expected_subsequence_2, 0, [(40, 45, 0.50, 1.50), (55, 120, 2.0, 2.01)]) testing_lib.add_chords_to_sequence(expected_subsequence_2, [('C', 0.0), ('G7', 1.0)]) expected_subsequence_2.total_time = 2.01 expected_subsequence_2.subsequence_info.start_time_offset = 2.0 expected_subsequence_2.subsequence_info.end_time_offset = 5.99 expected_subsequence_3 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 3 denominator: 4} tempos: { qpm: 80}""") testing_lib.add_track_to_sequence(expected_subsequence_3, 0, [(52, 99, 0.5, 0.75)]) testing_lib.add_chords_to_sequence(expected_subsequence_3, [('G7', 0.0), ('F', 0.55)]) expected_subsequence_3.total_time = 0.75 expected_subsequence_3.subsequence_info.start_time_offset = 4.25 expected_subsequence_3.subsequence_info.end_time_offset = 5.0 subsequences = sequences_lib.split_note_sequence_on_time_changes( sequence) self.assertEquals(3, len(subsequences)) self.assertProtoEquals(expected_subsequence_1, subsequences[0]) self.assertProtoEquals(expected_subsequence_2, subsequences[1]) self.assertProtoEquals(expected_subsequence_3, subsequences[2])
def testSplitNoteSequenceMultipleTimeChanges(self): # Tests splitting a NoteSequence on time changes, truncating notes on splits # that occur inside notes. sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} time_signatures: { time: 2.0 numerator: 3 denominator: 4} tempos: { qpm: 60} tempos: { time: 4.25 qpm: 80}""") testing_lib.add_track_to_sequence( sequence, 0, [(12, 100, 0.01, 10.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50), (55, 120, 4.0, 4.01), (52, 99, 4.75, 5.0)]) testing_lib.add_chords_to_sequence( sequence, [('C', 1.5), ('G7', 3.0), ('F', 4.8)]) expected_subsequence_1 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence( expected_subsequence_1, 0, [(12, 100, 0.01, 2.0), (11, 55, 0.22, 0.50)]) testing_lib.add_chords_to_sequence( expected_subsequence_1, [('C', 1.5)]) expected_subsequence_1.total_time = 2.0 expected_subsequence_1.subsequence_info.end_time_offset = 8.0 expected_subsequence_2 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 3 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence( expected_subsequence_2, 0, [(40, 45, 0.50, 1.50), (55, 120, 2.0, 2.01)]) testing_lib.add_chords_to_sequence( expected_subsequence_2, [('C', 0.0), ('G7', 1.0)]) expected_subsequence_2.total_time = 2.01 expected_subsequence_2.subsequence_info.start_time_offset = 2.0 expected_subsequence_2.subsequence_info.end_time_offset = 5.99 expected_subsequence_3 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 3 denominator: 4} tempos: { qpm: 80}""") testing_lib.add_track_to_sequence( expected_subsequence_3, 0, [(52, 99, 0.5, 0.75)]) testing_lib.add_chords_to_sequence( expected_subsequence_3, [('G7', 0.0), ('F', 0.55)]) expected_subsequence_3.total_time = 0.75 expected_subsequence_3.subsequence_info.start_time_offset = 4.25 expected_subsequence_3.subsequence_info.end_time_offset = 5.0 subsequences = sequences_lib.split_note_sequence_on_time_changes(sequence) self.assertEquals(3, len(subsequences)) self.assertProtoEquals(expected_subsequence_1, subsequences[0]) self.assertProtoEquals(expected_subsequence_2, subsequences[1]) self.assertProtoEquals(expected_subsequence_3, subsequences[2])