def testInferChordsForSequence(self): # Test non-quantized sequence. sequence = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence( sequence, 0, [(60, 100, 1.0, 3.0), (64, 100, 1.0, 2.0), (67, 100, 1.0, 2.0), (65, 100, 2.0, 3.0), (69, 100, 2.0, 3.0), (62, 100, 3.0, 5.0), (65, 100, 3.0, 4.0), (69, 100, 3.0, 4.0)]) expected_sequence = copy.copy(sequence) testing_lib.add_chords_to_sequence( expected_sequence, [('C', 1.0), ('F/C', 2.0), ('Dm', 3.0)]) sequences_lib.infer_chords_for_sequence(sequence) self.assertProtoEquals(expected_sequence, sequence) # Test quantized sequence. sequence = copy.copy(self.note_sequence) sequence.quantization_info.steps_per_quarter = 1 testing_lib.add_track_to_sequence( sequence, 0, [(60, 100, 1.1, 3.0), (64, 100, 1.0, 1.9), (67, 100, 1.0, 2.0), (65, 100, 2.0, 3.2), (69, 100, 2.1, 3.1), (62, 100, 2.9, 4.8), (65, 100, 3.0, 4.0), (69, 100, 3.0, 4.1)]) testing_lib.add_quantized_steps_to_sequence( sequence, [(1, 3), (1, 2), (1, 2), (2, 3), (2, 3), (3, 5), (3, 4), (3, 4)]) expected_sequence = copy.copy(sequence) testing_lib.add_chords_to_sequence( expected_sequence, [('C', 1.0), ('F/C', 2.0), ('Dm', 3.0)]) testing_lib.add_quantized_chord_steps_to_sequence( expected_sequence, [1, 2, 3]) sequences_lib.infer_chords_for_sequence(sequence) self.assertProtoEquals(expected_sequence, sequence)
def testExtractLeadSheetFragmentsCoincidentChords(self): testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 11)]) testing_lib.add_track_to_sequence( self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8), (50, 100, 33, 37), (52, 100, 34, 37)]) testing_lib.add_chords_to_sequence( self.note_sequence, [('C', 2), ('G7', 6), ('Cmaj7', 33), ('F', 33)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) lead_sheets, _ = lead_sheets_lib.extract_lead_sheet_fragments( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True, require_chords=True) melodies, _ = melodies_lib.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) chord_progressions, _ = chords_lib.extract_chords_for_melodies( quantized_sequence, melodies) # Last lead sheet should be rejected for coincident chords. self.assertEqual(list(melodies[:2]), list(lead_sheet.melody for lead_sheet in lead_sheets)) self.assertEqual(list(chord_progressions[:2]), list(lead_sheet.chords for lead_sheet in lead_sheets))
def testExtractSubsequence(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)]) testing_lib.add_control_changes_to_sequence( sequence, 0, [(0.0, 64, 127), (2.0, 64, 0), (4.0, 64, 127), (5.0, 64, 0)]) testing_lib.add_control_changes_to_sequence( sequence, 1, [(2.0, 64, 127)]) expected_subsequence = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence( expected_subsequence, 0, [(40, 45, 0.0, 1.0), (55, 120, 1.5, 1.51)]) testing_lib.add_chords_to_sequence( expected_subsequence, [('C', 0.0), ('G7', 0.5)]) testing_lib.add_control_changes_to_sequence( expected_subsequence, 0, [(0.0, 64, 0), (1.5, 64, 127)]) testing_lib.add_control_changes_to_sequence( expected_subsequence, 1, [(0.0, 64, 127)]) expected_subsequence.control_changes.sort(key=lambda cc: cc.time) expected_subsequence.total_time = 1.51 expected_subsequence.subsequence_info.start_time_offset = 2.5 expected_subsequence.subsequence_info.end_time_offset = 5.99 subsequence = sequences_lib.extract_subsequence(sequence, 2.5, 4.75) self.assertProtoEquals(expected_subsequence, subsequence)
def testQuantizeNoteSequenceAbsolute(self): testing_lib.add_track_to_sequence( self.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)]) testing_lib.add_chords_to_sequence( self.note_sequence, [('B7', 0.22), ('Em9', 4.0)]) testing_lib.add_control_changes_to_sequence( self.note_sequence, 0, [(2.0, 64, 127), (4.0, 64, 0)]) expected_quantized_sequence = copy.deepcopy(self.note_sequence) expected_quantized_sequence.quantization_info.steps_per_second = 4 testing_lib.add_quantized_steps_to_sequence( expected_quantized_sequence, [(0, 40), (1, 2), (10, 14), (16, 17), (19, 20)]) testing_lib.add_quantized_chord_steps_to_sequence( expected_quantized_sequence, [1, 16]) testing_lib.add_quantized_control_steps_to_sequence( expected_quantized_sequence, [8, 16]) quantized_sequence = sequences_lib.quantize_note_sequence_absolute( self.note_sequence, steps_per_second=4) self.assertProtoEquals(expected_quantized_sequence, quantized_sequence)
def testExtractChordsForMelodiesCoincidentChords(self): testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 11)]) testing_lib.add_track_to_sequence( self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8), (50, 100, 33, 37), (52, 100, 34, 37)]) testing_lib.add_chords_to_sequence( self.note_sequence, [('C', 2), ('G7', 6), ('E13', 8), ('Cmaj7', 8)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) melodies, _ = melodies_lib.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) chord_progressions, stats = chords_lib.extract_chords_for_melodies( quantized_sequence, melodies) expected = [[NO_CHORD, NO_CHORD, 'C', 'C', 'C', 'C', 'G7', 'G7'], ['Cmaj7', 'Cmaj7', 'Cmaj7', 'Cmaj7', 'Cmaj7']] stats_dict = dict((stat.name, stat) for stat in stats) self.assertIsNone(chord_progressions[0]) self.assertEqual(expected, [list(chords) for chords in chord_progressions[1:]]) self.assertEqual(stats_dict['coincident_chords'].count, 1)
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 testExtractLeadSheetFragmentsNoChords(self): testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 11)]) testing_lib.add_track_to_sequence( self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8), (50, 100, 33, 37), (52, 100, 34, 37)]) testing_lib.add_chords_to_sequence( self.note_sequence, [('C', 2), ('G7', 6), (NO_CHORD, 10)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) lead_sheets, stats = lead_sheets_lib.extract_lead_sheet_fragments( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True, require_chords=True) melodies, _ = melodies_lib.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) chord_progressions, _ = chords_lib.extract_chords_for_melodies( quantized_sequence, melodies) stats_dict = dict([(stat.name, stat) for stat in stats]) # Last lead sheet should be rejected for having no chords. self.assertEqual(list(melodies[:2]), list(lead_sheet.melody for lead_sheet in lead_sheets)) self.assertEqual(list(chord_progressions[:2]), list(lead_sheet.chords for lead_sheet in lead_sheets)) self.assertEqual(stats_dict['empty_chord_progressions'].count, 1)
def testExtractLeadSheetFragments(self): testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, .5, 1), (11, 1, 1.5, 2.75)]) testing_lib.add_track_to_sequence( self.note_sequence, 1, [(12, 127, .5, 1), (14, 50, 1.5, 2), (50, 100, 8.25, 9.25), (52, 100, 8.5, 9.25)]) testing_lib.add_chords_to_sequence( self.note_sequence, [('C', .5), ('G7', 1.5), ('Cmaj7', 8.25)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) lead_sheets, _ = lead_sheets_lib.extract_lead_sheet_fragments( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True, require_chords=True) melodies, _ = melodies_lib.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) chord_progressions, _ = chords_lib.extract_chords_for_melodies( quantized_sequence, melodies) self.assertEqual(list(melodies), list(lead_sheet.melody for lead_sheet in lead_sheets)) self.assertEqual(list(chord_progressions), list(lead_sheet.chords for lead_sheet in lead_sheets))
def testQuantizeNoteSequence(self): testing_lib.add_track_to_sequence( self.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), ], ) testing_lib.add_chords_to_sequence(self.note_sequence, [("B7", 0.22), ("Em9", 4.0)]) expected_quantized_sequence = copy.deepcopy(self.note_sequence) expected_quantized_sequence.quantization_info.steps_per_quarter = self.steps_per_quarter testing_lib.add_quantized_steps_to_sequence( expected_quantized_sequence, [(0, 40), (1, 2), (10, 14), (16, 17), (19, 20)] ) testing_lib.add_quantized_chord_steps_to_sequence(expected_quantized_sequence, [1, 16]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=self.steps_per_quarter ) self.assertProtoEquals(expected_quantized_sequence, quantized_sequence)
def testTfAugment(self): augmenter = data.NoteSequenceAugmenter( transpose_range=(-3, -3), stretch_range=(2.0, 2.0)) with self.test_session() as sess: sequence_str = tf.placeholder(tf.string) augmented_sequence_str_ = augmenter.tf_augment(sequence_str) augmented_sequence_str = sess.run( [augmented_sequence_str_], feed_dict={sequence_str: self.sequence.SerializeToString()}) augmented_sequence = music_pb2.NoteSequence.FromString( augmented_sequence_str[0]) expected_sequence = music_pb2.NoteSequence() expected_sequence.tempos.add(qpm=30) testing_lib.add_track_to_sequence( expected_sequence, 0, [(29, 100, 4, 8), (30, 100, 12, 22), (31, 100, 22, 26), (32, 100, 34, 36)]) testing_lib.add_track_to_sequence( expected_sequence, 1, [(57, 80, 8, 8.2), (58, 80, 24, 24.2)], is_drum=True) testing_lib.add_chords_to_sequence( expected_sequence, [('N.C.', 0), ('A', 16), ('Gbm', 32)]) self.assertEqual(expected_sequence, augmented_sequence)
def testExtractChords(self): testing_lib.add_chords_to_sequence( self.note_sequence, [('C', 2), ('G7', 6), ('F', 8)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) quantized_sequence.total_quantized_steps = 10 chord_progressions, _ = chords_lib.extract_chords(quantized_sequence) expected = [[NO_CHORD, NO_CHORD, 'C', 'C', 'C', 'C', 'G7', 'G7', 'F', 'F']] self.assertEqual(expected, [list(chords) for chords in chord_progressions])
def testFromQuantizedNoteSequenceWithCoincidentChords(self): testing_lib.add_chords_to_sequence( self.note_sequence, [('Am', 4), ('D7', 8), ('G13', 12), ('Csus', 12)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) chords = chords_lib.ChordProgression() with self.assertRaises(chords_lib.CoincidentChordsError): chords.from_quantized_sequence( quantized_sequence, start_step=0, end_step=16)
def testFromQuantizedNoteSequenceWithinSingleChord(self): testing_lib.add_chords_to_sequence( self.note_sequence, [('F', 0), ('Gm', 8)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) chords = chords_lib.ChordProgression() chords.from_quantized_sequence( quantized_sequence, start_step=4, end_step=6) expected = ['F'] * 2 self.assertEqual(expected, list(chords))
def testExtractSubsequencePastEnd(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', 18.0)]) with self.assertRaises(ValueError): sequences_lib.extract_subsequence(sequence, 15.0, 16.0)
def testExtractChordsAllTranspositions(self): testing_lib.add_chords_to_sequence( self.note_sequence, [('C', 1)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) quantized_sequence.total_quantized_steps = 2 chord_progressions, _ = chords_lib.extract_chords(quantized_sequence, all_transpositions=True) expected = list(zip([NO_CHORD] * 12, ['Gb', 'G', 'Ab', 'A', 'Bb', 'B', 'C', 'Db', 'D', 'Eb', 'E', 'F'])) self.assertEqual(expected, [tuple(chords) for chords in chord_progressions])
def setUp(self): sequence = music_pb2.NoteSequence() sequence.tempos.add(qpm=60) testing_lib.add_track_to_sequence( sequence, 0, [(32, 100, 2, 4), (33, 100, 6, 11), (34, 100, 11, 13), (35, 100, 17, 18)]) testing_lib.add_track_to_sequence( sequence, 1, [(57, 80, 4, 4.1), (58, 80, 12, 12.1)], is_drum=True) testing_lib.add_chords_to_sequence( sequence, [('N.C.', 0), ('C', 8), ('Am', 16)]) self.sequence = sequence
def testFromQuantizedNoteSequence(self): testing_lib.add_chords_to_sequence( self.note_sequence, [('Am', 4), ('D7', 8), ('G13', 12), ('Csus', 14)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) chords = chords_lib.ChordProgression() chords.from_quantized_sequence( quantized_sequence, start_step=0, end_step=16) expected = [NO_CHORD, NO_CHORD, NO_CHORD, NO_CHORD, 'Am', 'Am', 'Am', 'Am', 'D7', 'D7', 'D7', 'D7', 'G13', 'G13', 'Csus', 'Csus'] self.assertEqual(expected, list(chords))
def testAddChordsToSequence(self): note_sequence = music_pb2.NoteSequence(ticks_per_quarter=220) note_sequence.tempos.add(qpm=60.0) testing_lib.add_chords_to_sequence( note_sequence, [('N.C.', 0), ('C', 2), ('G7', 6)]) note_sequence.total_time = 8.0 expected_sequence = copy.deepcopy(note_sequence) del note_sequence.text_annotations[:] chords = [NO_CHORD, 'C', 'C', 'G7'] chord_times = [0.0, 2.0, 4.0, 6.0] chords_lib.add_chords_to_sequence(note_sequence, chords, chord_times) self.assertEqual(expected_sequence, note_sequence)
def testAugmentTranspose(self): augmenter = data.NoteSequenceAugmenter(transpose_range=(2, 2)) augmented_sequence = augmenter.augment(self.sequence) expected_sequence = music_pb2.NoteSequence() expected_sequence.tempos.add(qpm=60) testing_lib.add_track_to_sequence( expected_sequence, 0, [(34, 100, 2, 4), (35, 100, 6, 11), (36, 100, 11, 13), (37, 100, 17, 18)]) testing_lib.add_track_to_sequence( expected_sequence, 1, [(57, 80, 4, 4.1), (58, 80, 12, 12.1)], is_drum=True) testing_lib.add_chords_to_sequence( expected_sequence, [('N.C.', 0), ('D', 8), ('Bm', 16)]) self.assertEqual(expected_sequence, augmented_sequence)
def testAugmentStretch(self): augmenter = data.NoteSequenceAugmenter(stretch_range=(0.5, 0.5)) augmented_sequence = augmenter.augment(self.sequence) expected_sequence = music_pb2.NoteSequence() expected_sequence.tempos.add(qpm=120) testing_lib.add_track_to_sequence( expected_sequence, 0, [(32, 100, 1, 2), (33, 100, 3, 5.5), (34, 100, 5.5, 6.5), (35, 100, 8.5, 9)]) testing_lib.add_track_to_sequence( expected_sequence, 1, [(57, 80, 2, 2.05), (58, 80, 6, 6.05)], is_drum=True) testing_lib.add_chords_to_sequence( expected_sequence, [('N.C.', 0), ('C', 4), ('Am', 8)]) self.assertEqual(expected_sequence, augmented_sequence)
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 testToNoteSequenceChordConditioned(self): converter = data.OneHotMelodyConverter( steps_per_quarter=1, slice_bars=4, max_tensors_per_notesequence=1, chord_encoding=mm.MajorMinorChordOneHotEncoding()) tensors = converter.to_tensors( filter_instrument(self.sequence, 0)) sequences = converter.to_notesequences(tensors.outputs, tensors.controls) self.assertEqual(1, len(sequences)) expected_sequence = music_pb2.NoteSequence(ticks_per_quarter=220) expected_sequence.tempos.add(qpm=120) testing_lib.add_track_to_sequence( expected_sequence, 0, [(32, 80, 1.0, 2.0), (33, 80, 3.0, 5.5), (34, 80, 5.5, 6.5)]) testing_lib.add_chords_to_sequence( expected_sequence, [('N.C.', 0), ('F', 1), ('C', 4)]) self.assertProtoEquals(expected_sequence, sequences[0])
def testStretchNoteSequence(self): expected_stretched_sequence = copy.deepcopy(self.note_sequence) expected_stretched_sequence.tempos[0].qpm = 40 testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, 0.0, 10.0), (11, 55, 0.2, 0.5), (40, 45, 2.5, 3.5)]) testing_lib.add_track_to_sequence( expected_stretched_sequence, 0, [(12, 100, 0.0, 15.0), (11, 55, 0.3, 0.75), (40, 45, 3.75, 5.25)]) testing_lib.add_chords_to_sequence( self.note_sequence, [('B7', 0.5), ('Em9', 2.0)]) testing_lib.add_chords_to_sequence( expected_stretched_sequence, [('B7', 0.75), ('Em9', 3.0)]) stretched_sequence = sequences_lib.stretch_note_sequence( self.note_sequence, stretch_factor=1.5) self.assertProtoEquals(expected_stretched_sequence, stretched_sequence)
def testEncodeNoteSequence(self): encoder = music_encoders.TextChordsEncoder(steps_per_quarter=1) ns = music_pb2.NoteSequence() ns.tempos.add(qpm=60) testing_lib.add_chords_to_sequence( ns, [('C', 1), ('Dm', 3), ('Bdim', 4)]) ns.total_time = 5.0 ids = encoder.encode_note_sequence(ns) expected_ids = [ 2, # no-chord 3, # C major 3, # C major 17, # D minor 50 # B diminished ] self.assertEqual(expected_ids, ids)
def testExtractSubsequence(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 = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence( expected_subsequence, 0, [(40, 45, 0.0, 1.0), (55, 120, 1.5, 1.51)]) testing_lib.add_chords_to_sequence( expected_subsequence, [('C', 0.0), ('G7', 0.5)]) expected_subsequence.total_time = 2.25 expected_subsequence.subsequence_info.start_time_offset = 2.5 expected_subsequence.subsequence_info.end_time_offset = 5.25 subsequence = sequences_lib.extract_subsequence(sequence, 2.5, 4.75) self.assertProtoEquals(expected_subsequence, subsequence)
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 testEncodeNoteSequence(self): encoder = music_encoders.CompositeScoreEncoder([ music_encoders.TextChordsEncoder(steps_per_quarter=4), music_encoders.TextMelodyEncoder( steps_per_quarter=4, min_pitch=21, max_pitch=108) ]) ns = music_pb2.NoteSequence() ns.tempos.add(qpm=60) testing_lib.add_chords_to_sequence(ns, [('C', 0.5), ('Dm', 1.0)]) testing_lib.add_track_to_sequence( ns, 0, [(60, 127, 0.0, 0.25), (62, 127, 0.25, 0.75), (64, 127, 1.25, 2.0)]) chord_ids, melody_ids = zip(*encoder.encode_note_sequence(ns)) expected_chord_ids = [ 2, # no-chord 2, # no-chord 3, # C major 3, # C major 17, # D minor 17, # D minor 17, # D minor 17 # D minor ] expected_melody_ids = [ 43, # ON(60) 45, # ON(62) 2, # HOLD(62) 3, # OFF(62) 2, # REST 47, # ON(64) 2, # HOLD(64) 2 # HOLD(64) ] self.assertEqual(expected_chord_ids, list(chord_ids)) self.assertEqual(expected_melody_ids, list(melody_ids))
def testLeadSheetExtractor(self): note_sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence( note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 7)]) testing_lib.add_track_to_sequence( note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8)]) testing_lib.add_chords_to_sequence( note_sequence, [('Cm7', 2), ('F9', 4), ('G7b9', 6)]) quantized_sequence = sequences_lib.quantize_note_sequence( note_sequence, steps_per_quarter=1) expected_melody_events = [ [NO_EVENT, NO_EVENT, 12, NO_EVENT, NOTE_OFF, NO_EVENT, 11], [NO_EVENT, NO_EVENT, 12, NO_EVENT, NOTE_OFF, NO_EVENT, 14, NO_EVENT]] expected_chord_events = [ [NO_CHORD, NO_CHORD, 'Cm7', 'Cm7', 'F9', 'F9', 'G7b9'], [NO_CHORD, NO_CHORD, 'Cm7', 'Cm7', 'F9', 'F9', 'G7b9', 'G7b9']] expected_lead_sheets = [] for melody_events, chord_events in zip(expected_melody_events, expected_chord_events): melody = melodies_lib.Melody( melody_events, steps_per_quarter=1, steps_per_bar=4) chords = chords_lib.ChordProgression( chord_events, steps_per_quarter=1, steps_per_bar=4) lead_sheet = lead_sheets_lib.LeadSheet(melody, chords) expected_lead_sheets.append(lead_sheet) unit = lead_sheet_pipelines.LeadSheetExtractor( min_bars=1, min_unique_pitches=1, gap_bars=1, all_transpositions=False) self._unit_transform_test(unit, quantized_sequence, expected_lead_sheets)
def testChordsExtractor(self): note_sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_chords_to_sequence( note_sequence, [('C', 2), ('Am', 4), ('F', 5)]) quantized_sequence = sequences_lib.quantize_note_sequence( note_sequence, steps_per_quarter=1) quantized_sequence.total_quantized_steps = 8 expected_events = [[NO_CHORD, NO_CHORD, 'C', 'C', 'Am', 'F', 'F', 'F']] expected_chord_progressions = [] for events_list in expected_events: chords = chords_lib.ChordProgression( events_list, steps_per_quarter=1, steps_per_bar=4) expected_chord_progressions.append(chords) unit = chord_pipelines.ChordsExtractor(all_transpositions=False) self._unit_transform_test(unit, quantized_sequence, expected_chord_progressions)
def testToNoteSequenceMultipleChunksWithChords(self): sequence = copy.deepcopy(self.sequence) testing_lib.add_track_to_sequence( sequence, 0, [(64, 100, 0, 2), (60, 100, 0, 4), (67, 100, 2, 4), (62, 100, 4, 6), (59, 100, 4, 8), (67, 100, 6, 8), ]) testing_lib.add_track_to_sequence( sequence, 1, [(40, 100, 0, 0.125), (50, 100, 0, 0.125), (50, 100, 2, 2.125), (40, 100, 4, 4.125), (50, 100, 4, 4.125), (50, 100, 6, 6.125), ], is_drum=True) testing_lib.add_chords_to_sequence( sequence, [('C', 0), ('G', 4)]) converter = data_hierarchical.MultiInstrumentPerformanceConverter( hop_size_bars=4, chunk_size_bars=2, chord_encoding=mm.MajorMinorChordOneHotEncoding()) tensors = converter.to_tensors(sequence) self.assertEquals(1, len(tensors.outputs)) sequences = converter.to_notesequences(tensors.outputs, tensors.controls) self.assertEquals(1, len(sequences)) self.assertProtoEquals(sequence, sequences[0])
def testExtractChordsForMelodies(self): testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 11)]) testing_lib.add_track_to_sequence( self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8), (50, 100, 33, 37), (52, 100, 34, 37)]) testing_lib.add_chords_to_sequence( self.note_sequence, [('C', 2), ('G7', 6), ('Cmaj7', 33)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) melodies, _ = melodies_lib.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) chord_progressions, _ = chords_lib.extract_chords_for_melodies( quantized_sequence, melodies) expected = [[NO_CHORD, NO_CHORD, 'C', 'C', 'C', 'C', 'G7', 'G7', 'G7', 'G7', 'G7'], [NO_CHORD, NO_CHORD, 'C', 'C', 'C', 'C', 'G7', 'G7'], ['G7', 'Cmaj7', 'Cmaj7', 'Cmaj7', 'Cmaj7']] self.assertEqual(expected, [list(chords) for chords in chord_progressions])
def testEventListChordsWithMelodies(self): note_sequence = music_pb2.NoteSequence(ticks_per_quarter=220) note_sequence.tempos.add(qpm=60.0) testing_lib.add_chords_to_sequence( note_sequence, [('N.C.', 0), ('C', 2), ('G7', 6)]) note_sequence.total_time = 8.0 melodies = [ melodies_lib.Melody([60, -2, -2, -1], start_step=0, steps_per_quarter=1, steps_per_bar=4), melodies_lib.Melody([62, -2, -2, -1], start_step=4, steps_per_quarter=1, steps_per_bar=4), ] quantized_sequence = sequences_lib.quantize_note_sequence( note_sequence, steps_per_quarter=1) chords = chords_lib.event_list_chords(quantized_sequence, melodies) expected_chords = [ [NO_CHORD, NO_CHORD, 'C', 'C'], ['C', 'C', 'G7', 'G7'] ] self.assertEqual(expected_chords, chords)
def testExtractLeadSheetFragmentsNoChords(self): music_testing_lib.add_track_to_sequence(self.note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 11)]) music_testing_lib.add_track_to_sequence(self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8), (50, 100, 33, 37), (52, 100, 34, 37)]) music_testing_lib.add_chords_to_sequence(self.note_sequence, [('C', 2), ('G7', 6), (NO_CHORD, 10)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) lead_sheets, stats = lead_sheet_pipelines.extract_lead_sheet_fragments( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True, require_chords=True) melodies, _ = melody_pipelines.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) chord_progressions, _ = chord_pipelines.extract_chords_for_melodies( quantized_sequence, melodies) stats_dict = dict((stat.name, stat) for stat in stats) # Last lead sheet should be rejected for having no chords. self.assertEqual(list(melodies[:2]), list(lead_sheet.melody for lead_sheet in lead_sheets)) self.assertEqual(list(chord_progressions[:2]), list(lead_sheet.chords for lead_sheet in lead_sheets)) self.assertEqual(stats_dict['empty_chord_progressions'].count, 1)
def testSplitNoteSequenceSkipSplitsInsideNotes(self): # Tests splitting a NoteSequence at regular hop size, skipping splits that # would have occurred inside a note. sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") 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', 0.0), ('G7', 3.0), ('F', 4.5)]) 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, 3.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.50)]) testing_lib.add_chords_to_sequence( expected_subsequence_1, [('C', 0.0), ('G7', 3.0)]) expected_subsequence_1.total_time = 3.50 expected_subsequence_1.subsequence_info.end_time_offset = 1.5 expected_subsequence_2 = 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_2, 0, [(55, 120, 0.0, 0.01), (52, 99, 0.75, 1.0)]) testing_lib.add_chords_to_sequence( expected_subsequence_2, [('G7', 0.0), ('F', 0.5)]) expected_subsequence_2.total_time = 1.0 expected_subsequence_2.subsequence_info.start_time_offset = 4.0 subsequences = sequences_lib.split_note_sequence( sequence, hop_size_seconds=2.0, skip_splits_inside_notes=True) self.assertEquals(2, len(subsequences)) self.assertProtoEquals(expected_subsequence_1, subsequences[0]) self.assertProtoEquals(expected_subsequence_2, subsequences[1])
def testToNoteSequenceWithChords(self): sequence = copy.deepcopy(self.sequence) testing_lib.add_track_to_sequence(sequence, 0, [ (64, 100, 0, 2), (60, 100, 0, 4), (67, 100, 2, 4), (62, 100, 4, 6), (59, 100, 4, 8), (67, 100, 6, 8), ]) testing_lib.add_track_to_sequence(sequence, 1, [ (40, 100, 0, 0.125), (50, 100, 0, 0.125), (50, 100, 2, 2.125), (40, 100, 4, 4.125), (50, 100, 4, 4.125), (50, 100, 6, 6.125), ], is_drum=True) testing_lib.add_chords_to_sequence(sequence, [('C', 0), ('G', 4)]) converter = data_hierarchical.MultiInstrumentPerformanceConverter( hop_size_bars=2, chunk_size_bars=2, chord_encoding=mm.MajorMinorChordOneHotEncoding()) tensors = converter.to_tensors(sequence) self.assertEqual(2, len(tensors.outputs)) sequences = converter.to_notesequences(tensors.outputs, tensors.controls) self.assertEqual(2, len(sequences)) sequence1 = copy.deepcopy(self.sequence) testing_lib.add_track_to_sequence(sequence1, 0, [(64, 100, 0, 2), (60, 100, 0, 4), (67, 100, 2, 4)]) testing_lib.add_track_to_sequence(sequence1, 1, [(40, 100, 0, 0.125), (50, 100, 0, 0.125), (50, 100, 2, 2.125)], is_drum=True) testing_lib.add_chords_to_sequence(sequence1, [('C', 0)]) self.assertProtoEquals(sequence1, sequences[0]) sequence2 = copy.deepcopy(self.sequence) testing_lib.add_track_to_sequence(sequence2, 0, [(62, 100, 0, 2), (59, 100, 0, 4), (67, 100, 2, 4)]) testing_lib.add_track_to_sequence(sequence2, 1, [(40, 100, 0, 0.125), (50, 100, 0, 0.125), (50, 100, 2, 2.125)], is_drum=True) testing_lib.add_chords_to_sequence(sequence2, [('G', 0)]) self.assertProtoEquals(sequence2, sequences[1])
def setUp(self): sequence = music_pb2.NoteSequence() sequence.tempos.add(qpm=60) testing_lib.add_track_to_sequence(sequence, 0, [(32, 100, 2, 4), (33, 1, 6, 11), (34, 1, 11, 13), (35, 1, 17, 19)]) testing_lib.add_track_to_sequence(sequence, 1, [(35, 127, 2, 4), (36, 50, 6, 8), (71, 100, 33, 37), (73, 100, 34, 37), (33, 1, 50, 55), (34, 1, 55, 56)]) testing_lib.add_chords_to_sequence(sequence, [('F', 2), ('C', 8), ('Am', 16), ('N.C.', 20), ('Bb7', 32), ('G', 36), ('F', 48), ('C', 52)]) self.sequence = sequence # Subtract min pitch (21). expected_unsliced_events = [ (NO_EVENT, NO_EVENT, 11, NO_EVENT, NOTE_OFF, NO_EVENT, 12, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, 13, NO_EVENT, NOTE_OFF, NO_EVENT, NO_EVENT), (NO_EVENT, 14, NO_EVENT, NOTE_OFF), (NO_EVENT, NO_EVENT, 14, NO_EVENT, NOTE_OFF, NO_EVENT, 15, NO_EVENT), (NO_EVENT, 50, 52, NO_EVENT, NO_EVENT, NOTE_OFF, NO_EVENT, NO_EVENT), (NO_EVENT, NO_EVENT, 12, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, 13), ] self.expected_unsliced_labels = [ np.array(es) + 2 for es in expected_unsliced_events ] expected_sliced_events = [(NO_EVENT, NO_EVENT, 11, NO_EVENT, NOTE_OFF, NO_EVENT, 12, NO_EVENT), (NO_EVENT, NO_EVENT, 12, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, 13), (NO_EVENT, NO_EVENT, NO_EVENT, 13, NO_EVENT, NOTE_OFF, NO_EVENT, NO_EVENT), (NO_EVENT, NO_EVENT, 14, NO_EVENT, NOTE_OFF, NO_EVENT, 15, NO_EVENT), (NO_EVENT, 50, 52, NO_EVENT, NO_EVENT, NOTE_OFF, NO_EVENT, NO_EVENT)] self.expected_sliced_labels = [ np.array(es) + 2 for es in expected_sliced_events ] chord_encoding = mm.MajorMinorChordOneHotEncoding() expected_unsliced_chord_events = [ (NO_CHORD, NO_CHORD, 'F', 'F', 'F', 'F', 'F', 'F', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'), ('Am', 'Am', 'Am', 'Am'), (NO_CHORD, NO_CHORD, 'F', 'F', 'F', 'F', 'F', 'F'), ('Bb7', 'Bb7', 'Bb7', 'Bb7', 'G', 'G', 'G', 'G'), ('F', 'F', 'F', 'F', 'C', 'C', 'C', 'C'), ] self.expected_unsliced_chord_labels = [ np.array([chord_encoding.encode_event(e) for e in es]) for es in expected_unsliced_chord_events ] expected_sliced_chord_events = [ (NO_CHORD, NO_CHORD, 'F', 'F', 'F', 'F', 'F', 'F'), ('F', 'F', 'F', 'F', 'C', 'C', 'C', 'C'), ('C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'), (NO_CHORD, NO_CHORD, 'F', 'F', 'F', 'F', 'F', 'F'), ('Bb7', 'Bb7', 'Bb7', 'Bb7', 'G', 'G', 'G', 'G'), ] self.expected_sliced_chord_labels = [ np.array([chord_encoding.encode_event(e) for e in es]) for es in expected_sliced_chord_events ] self.converter_class = data.OneHotMelodyConverter
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 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.01 expected_subsequence_1.subsequence_info.end_time_offset = 0.99 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 testSplitNoteSequence(self): # Tests splitting a NoteSequence at regular hop size, truncating notes. sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_track_to_sequence(sequence, 0, [(12, 100, 0.01, 8.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.0), ('G7', 2.0), ('F', 4.0)]) 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, 3.0), (11, 55, 0.22, 0.50), (40, 45, 2.50, 3.0)]) testing_lib.add_chords_to_sequence(expected_subsequence_1, [('C', 1.0), ('G7', 2.0)]) expected_subsequence_1.total_time = 3.0 expected_subsequence_1.subsequence_info.end_time_offset = 5.0 expected_subsequence_2 = 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_2, 0, [(55, 120, 1.0, 1.01), (52, 99, 1.75, 2.0)]) testing_lib.add_chords_to_sequence(expected_subsequence_2, [('G7', 0.0), ('F', 1.0)]) expected_subsequence_2.total_time = 2.0 expected_subsequence_2.subsequence_info.start_time_offset = 3.0 expected_subsequence_2.subsequence_info.end_time_offset = 3.0 expected_subsequence_3 = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") testing_lib.add_chords_to_sequence(expected_subsequence_3, [('F', 0.0)]) expected_subsequence_3.total_time = 0.0 expected_subsequence_3.subsequence_info.start_time_offset = 6.0 expected_subsequence_3.subsequence_info.end_time_offset = 2.0 subsequences = sequences_lib.split_note_sequence(sequence, hop_size_seconds=3.0) 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 setUp(self): sequence = music_pb2.NoteSequence() sequence.tempos.add(qpm=60) # Mel 1, coverage bars: [3, 9] / [2, 9] testing_lib.add_track_to_sequence(sequence, 1, [(51, 1, 13, 37)]) # Mel 2, coverage bars: [1, 3] / [0, 4] testing_lib.add_track_to_sequence(sequence, 2, [(52, 1, 4, 16)]) # Bass, coverage bars: [0, 1], [4, 6] / [0, 7] testing_lib.add_track_to_sequence(sequence, 3, [(50, 1, 2, 5), (49, 1, 16, 25)]) # Drum, coverage bars: [0, 2], [6, 7] / [0, 3], [5, 8] testing_lib.add_track_to_sequence(sequence, 4, [(35, 1, 0, 1), (40, 1, 4, 5), (35, 1, 9, 9), (35, 1, 25, 25), (40, 1, 29, 29)], is_drum=True) # Chords. testing_lib.add_chords_to_sequence(sequence, [('C', 4), ('Am', 16), ('G', 32)]) for n in sequence.notes: if n.instrument == 1: n.program = 0 elif n.instrument == 2: n.program = 10 elif n.instrument == 3: n.program = 33 self.sequence = sequence m1 = np.array([NO_EVENT] * 13 + [30] + [NO_EVENT] * 23 + [NOTE_OFF] + [NO_EVENT] * 2, np.int32) + 2 m2 = np.array([NO_EVENT] * 4 + [31] + [NO_EVENT] * 11 + [NOTE_OFF] + [NO_EVENT] * 23, np.int32) + 2 b = np.array([NO_EVENT, NO_EVENT, 29, NO_EVENT, NO_EVENT, NOTE_OFF] + [NO_EVENT] * 10 + [28] + [NO_EVENT] * 8 + [NOTE_OFF] + [NO_EVENT] * 14, np.int32) + 2 d = ( [ 1, NO_DRUMS, NO_DRUMS, NO_DRUMS, 2, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, 1, NO_DRUMS, NO_DRUMS ] + [NO_DRUMS] * 12 + [NO_DRUMS, 1, NO_DRUMS, NO_DRUMS, NO_DRUMS, 2, NO_DRUMS, NO_DRUMS ] + [NO_DRUMS] * 4) c = [ NO_CHORD, NO_CHORD, NO_CHORD, NO_CHORD, 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'Am', 'G', 'G', 'G', 'G' ] expected_sliced_sets = [ ((2, 4), (m1, b, d)), ((5, 7), (m1, b, d)), ((6, 8), (m1, b, d)), ((0, 2), (m2, b, d)), ((1, 3), (m2, b, d)), ((2, 4), (m2, b, d)), ] self.expected_sliced_labels = [ np.stack([l[i * 4:j * 4] for l in x]) for (i, j), x in expected_sliced_sets ] chord_encoding = mm.MajorMinorChordOneHotEncoding() expected_sliced_chord_events = [ c[i * 4:j * 4] for (i, j), _ in expected_sliced_sets ] self.expected_sliced_chord_labels = [ np.array([chord_encoding.encode_event(e) for e in es]) for es in expected_sliced_chord_events ]
def testSplitNoteSequenceCoincidentTimeChanges(self): # Tests splitting a NoteSequence on time changes for a NoteSequence that has # two time changes occurring simultaneously. 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])