def testExtractDrumTracksTooShort(self): music_testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 127, 3, 4), (14, 50, 6, 7)], is_drum=True) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) drum_tracks, _ = drum_pipelines.extract_drum_tracks( quantized_sequence, min_bars=2, gap_bars=1) drum_tracks = [list(drums) for drums in drum_tracks] self.assertEqual([], drum_tracks) del self.note_sequence.notes[:] music_testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 127, 3, 4), (14, 50, 7, 8)], is_drum=True) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) drum_tracks, _ = drum_pipelines.extract_drum_tracks( quantized_sequence, min_bars=2, gap_bars=1) drum_tracks = [list(drums) for drums in drum_tracks] self.assertEqual( [[NO_DRUMS, NO_DRUMS, NO_DRUMS, DRUMS(12), NO_DRUMS, NO_DRUMS, NO_DRUMS, DRUMS(14)]], drum_tracks)
def testExtractPianorollSequences(self): music_testing_lib.add_track_to_sequence(self.note_sequence, 0, [(60, 100, 0.0, 4.0)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) seqs, _ = pianoroll_pipeline.extract_pianoroll_sequences( quantized_sequence) self.assertLen(seqs, 1) seqs, _ = pianoroll_pipeline.extract_pianoroll_sequences( quantized_sequence, min_steps_discard=2, max_steps_discard=5) self.assertLen(seqs, 1) self.note_sequence.notes[0].end_time = 1.0 self.note_sequence.total_time = 1.0 quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) seqs, _ = pianoroll_pipeline.extract_pianoroll_sequences( quantized_sequence, min_steps_discard=3, max_steps_discard=5) self.assertEmpty(seqs) self.note_sequence.notes[0].end_time = 10.0 self.note_sequence.total_time = 10.0 quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) seqs, _ = pianoroll_pipeline.extract_pianoroll_sequences( quantized_sequence, min_steps_discard=3, max_steps_discard=5) self.assertEmpty(seqs)
def testExtractPolyphonicSequences(self): testing_lib.add_track_to_sequence(self.note_sequence, 0, [(60, 100, 0.0, 4.0)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) seqs, _ = polyphony_lib.extract_polyphonic_sequences( quantized_sequence) self.assertEqual(1, len(seqs)) seqs, _ = polyphony_lib.extract_polyphonic_sequences( quantized_sequence, min_steps_discard=2, max_steps_discard=5) self.assertEqual(1, len(seqs)) self.note_sequence.notes[0].end_time = 1.0 self.note_sequence.total_time = 1.0 quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) seqs, _ = polyphony_lib.extract_polyphonic_sequences( quantized_sequence, min_steps_discard=3, max_steps_discard=5) self.assertEqual(0, len(seqs)) self.note_sequence.notes[0].end_time = 10.0 self.note_sequence.total_time = 10.0 quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) seqs, _ = polyphony_lib.extract_polyphonic_sequences( quantized_sequence, min_steps_discard=3, max_steps_discard=5) self.assertEqual(0, len(seqs))
def testExtractMelodiesMelodyTooShort(self): music_testing_lib.add_track_to_sequence(self.note_sequence, 0, [(12, 127, 2, 4), (14, 50, 6, 7)]) music_testing_lib.add_track_to_sequence(self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8)]) music_testing_lib.add_track_to_sequence(self.note_sequence, 2, [(12, 127, 2, 4), (14, 50, 6, 9)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) expected = [[ NO_EVENT, NO_EVENT, 12, NO_EVENT, NOTE_OFF, NO_EVENT, 14, NO_EVENT ], [ NO_EVENT, NO_EVENT, 12, NO_EVENT, NOTE_OFF, NO_EVENT, 14, NO_EVENT, NO_EVENT ]] melodies, _ = melody_pipelines.extract_melodies( quantized_sequence, min_bars=2, gap_bars=1, min_unique_pitches=2, ignore_polyphonic_notes=True) melodies = [list(melody) for melody in melodies] self.assertEqual(expected, melodies)
def testExtractMultipleMelodiesFromSameTrack(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)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) expected = [[ NO_EVENT, NO_EVENT, 12, NO_EVENT, NOTE_OFF, NO_EVENT, 11, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT ], [ NO_EVENT, NO_EVENT, 12, NO_EVENT, NOTE_OFF, NO_EVENT, 14, NO_EVENT ], [NO_EVENT, 50, 52, NO_EVENT, NO_EVENT]] melodies, _ = melody_pipelines.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) melodies = sorted([list(melody) for melody in melodies]) self.assertEqual(expected, melodies)
def testExtractPerformancesRelativeQuantized(self): self.note_sequence.tempos.add(qpm=60.0) music_testing_lib.add_track_to_sequence( self.note_sequence, 0, [(60, 100, 0.0, 4.0)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=100) perfs, _ = performance_pipeline.extract_performances \ (quantized_sequence) self.assertLen(perfs, 1) perfs, _ = performance_pipeline.extract_performances( quantized_sequence, min_events_discard=1, max_events_truncate=10) self.assertLen(perfs, 1) perfs, _ = performance_pipeline.extract_performances( quantized_sequence, min_events_discard=8, max_events_truncate=10) self.assertEmpty(perfs) perfs, _ = performance_pipeline.extract_performances( quantized_sequence, min_events_discard=1, max_events_truncate=3) self.assertLen(perfs, 1) self.assertLen(perfs[0], 3) perfs, _ = performance_pipeline.extract_performances( quantized_sequence, max_steps_truncate=100) self.assertLen(perfs, 1) self.assertEqual(100, perfs[0].num_steps)
def testFromQuantizedNoteSequenceNotCommonTimeSig(self): self.note_sequence.time_signatures[0].numerator = 7 self.note_sequence.time_signatures[0].denominator = 8 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)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) melody = melodies_lib.Melody() melody.from_quantized_sequence(quantized_sequence, search_start_step=0, instrument=0) expected = ([ 12, 11, NOTE_OFF, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, 40, NO_EVENT, NO_EVENT, NO_EVENT, NOTE_OFF, NO_EVENT, 55, NOTE_OFF, NO_EVENT, 52 ]) self.assertEqual(expected, list(melody)) self.assertEqual(14, melody.steps_per_bar)
def testMelodyExtractor(self): note_sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") music_testing_lib.add_track_to_sequence(note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 7)]) music_testing_lib.add_track_to_sequence(note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8)]) quantized_sequence = sequences_lib.quantize_note_sequence( note_sequence, steps_per_quarter=1) expected_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_melodies = [] for events_list in expected_events: melody = melodies_lib.Melody(events_list, steps_per_quarter=1, steps_per_bar=4) expected_melodies.append(melody) unit = melody_pipelines.MelodyExtractor(min_bars=1, min_unique_pitches=1, gap_bars=1) self._unit_transform_test(unit, quantized_sequence, expected_melodies)
def testInferChordsForSequence(self): sequence = music_pb2.NoteSequence() testing_lib.add_track_to_sequence( sequence, 0, [ (60, 100, 0.0, 1.0), (64, 100, 0.0, 1.0), (67, 100, 0.0, 1.0), # C (62, 100, 1.0, 2.0), (65, 100, 1.0, 2.0), (69, 100, 1.0, 2.0), # Dm (60, 100, 2.0, 3.0), (65, 100, 2.0, 3.0), (69, 100, 2.0, 3.0), # F (59, 100, 3.0, 4.0), (62, 100, 3.0, 4.0), (67, 100, 3.0, 4.0) ]) # G quantized_sequence = sequences_lib.quantize_note_sequence( sequence, steps_per_quarter=4) chord_inference.infer_chords_for_sequence(quantized_sequence, chords_per_bar=2) expected_chords = [('C', 0.0), ('Dm', 1.0), ('F', 2.0), ('G', 3.0)] chords = [(ta.text, ta.time) for ta in quantized_sequence.text_annotations] self.assertEqual(expected_chords, chords)
def transform(self, note_sequence): try: if self._steps_per_quarter is not None: quantized_sequence = sequences_lib.quantize_note_sequence( note_sequence, self._steps_per_quarter) else: quantized_sequence = sequences_lib.quantize_note_sequence_absolute( note_sequence, self._steps_per_second) return [quantized_sequence] except sequences_lib.MultipleTimeSignatureError as e: tf.logging.warning( 'Multiple time signatures in NoteSequence %s: %s', note_sequence.filename, e) self._set_stats([ statistics.Counter( 'sequences_discarded_because_multiple_time_signatures', 1) ]) return [] except sequences_lib.MultipleTempoError as e: tf.logging.warning('Multiple tempos found in NoteSequence %s: %s', note_sequence.filename, e) self._set_stats([ statistics.Counter( 'sequences_discarded_because_multiple_tempos', 1) ]) return [] except sequences_lib.BadTimeSignatureError as e: tf.logging.warning('Bad time signature in NoteSequence %s: %s', note_sequence.filename, e) self._set_stats([ statistics.Counter( 'sequences_discarded_because_bad_time_signature', 1) ]) return []
def midi_file_to_melody(midi_file, steps_per_quarter=4, qpm=None, ignore_polyphonic_notes=True): """Loads a melody from a MIDI file. Args: midi_file: Absolute path to MIDI file. steps_per_quarter: Quantization of Melody. For example, 4 = 16th notes. qpm: Tempo in quarters per a minute. If not set, tries to use the first tempo of the midi track and defaults to note_seq.DEFAULT_QUARTERS_PER_MINUTE if fails. ignore_polyphonic_notes: Only use the highest simultaneous note if True. Returns: A Melody object extracted from the MIDI file. """ sequence = midi_io.midi_file_to_sequence_proto(midi_file) if qpm is None: if sequence.tempos: qpm = sequence.tempos[0].qpm else: qpm = constants.DEFAULT_QUARTERS_PER_MINUTE quantized_sequence = sequences_lib.quantize_note_sequence( sequence, steps_per_quarter=steps_per_quarter) melody = Melody() melody.from_quantized_sequence( quantized_sequence, ignore_polyphonic_notes=ignore_polyphonic_notes) return melody
def testExtractChordsForMelodies(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), ('Cmaj7', 33)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) 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) 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 testExtractLeadSheetFragments(self): music_testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, .5, 1), (11, 1, 1.5, 2.75)]) music_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)]) music_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_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) 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 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 testExtractMelodiesTooFewPitches(self): # Test that extract_melodies discards melodies with too few pitches where # pitches are equivalent by octave. music_testing_lib.add_track_to_sequence(self.note_sequence, 0, [(12, 100, 0, 1), (13, 100, 1, 2), (18, 100, 2, 3), (24, 100, 3, 4), (25, 100, 4, 5)]) music_testing_lib.add_track_to_sequence(self.note_sequence, 1, [(12, 100, 0, 1), (13, 100, 1, 2), (18, 100, 2, 3), (25, 100, 3, 4), (26, 100, 4, 5)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) expected = [[12, 13, 18, 25, 26]] melodies, _ = melody_pipelines.extract_melodies( quantized_sequence, min_bars=1, gap_bars=1, min_unique_pitches=4, ignore_polyphonic_notes=True) melodies = [list(melody) for melody in melodies] self.assertEqual(expected, melodies)
def testExtractChordsForMelodiesCoincidentChords(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), ('E13', 8), ('Cmaj7', 8)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) melodies, _ = melody_pipelines.extract_melodies( quantized_sequence, min_bars=1, gap_bars=2, min_unique_pitches=2, ignore_polyphonic_notes=True) chord_progressions, stats = chord_pipelines.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 testExtractMelodiesSimple(self): music_testing_lib.add_track_to_sequence(self.note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 7)]) music_testing_lib.add_track_to_sequence(self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 9)]) music_testing_lib.add_track_to_sequence(self.note_sequence, 9, [(13, 100, 2, 4), (15, 25, 6, 8)], is_drum=True) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) expected = [[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, NO_EVENT ]] melodies, _ = melody_pipelines.extract_melodies( quantized_sequence, min_bars=1, gap_bars=1, min_unique_pitches=2, ignore_polyphonic_notes=True) self.assertLen(melodies, 2) self.assertIsInstance(melodies[0], melodies_lib.Melody) self.assertIsInstance(melodies[1], melodies_lib.Melody) melodies = sorted([list(melody) for melody in melodies]) self.assertEqual(expected, melodies)
def testFromRelativeQuantizedNoteSequence(self): self.note_sequence.tempos.add(qpm=60.0) testing_lib.add_track_to_sequence(self.note_sequence, 0, [(60, 100, 0.0, 4.0), (64, 100, 0.0, 3.0), (67, 100, 1.0, 2.0)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=100) performance = performance_lib.MetricPerformance(quantized_sequence) self.assertEqual(100, performance.steps_per_quarter) pe = performance_lib.PerformanceEvent expected_performance = [ pe(pe.NOTE_ON, 60), pe(pe.NOTE_ON, 64), pe(pe.TIME_SHIFT, 100), pe(pe.NOTE_ON, 67), pe(pe.TIME_SHIFT, 100), pe(pe.NOTE_OFF, 67), pe(pe.TIME_SHIFT, 100), pe(pe.NOTE_OFF, 64), pe(pe.TIME_SHIFT, 100), pe(pe.NOTE_OFF, 60), ] self.assertEqual(expected_performance, list(performance))
def testDrumsExtractor(self): note_sequence = common_testing_lib.parse_test_proto( music_pb2.NoteSequence, """ time_signatures: { numerator: 4 denominator: 4} tempos: { qpm: 60}""") music_testing_lib.add_track_to_sequence( note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 7), (12, 1, 6, 8)], is_drum=True) music_testing_lib.add_track_to_sequence( note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 8)]) quantized_sequence = sequences_lib.quantize_note_sequence( note_sequence, steps_per_quarter=1) expected_events = [ [NO_DRUMS, NO_DRUMS, DRUMS(12), NO_DRUMS, NO_DRUMS, NO_DRUMS, DRUMS(11, 12)]] expected_drum_tracks = [] for events_list in expected_events: drums = drums_lib.DrumTrack( events_list, steps_per_quarter=1, steps_per_bar=4) expected_drum_tracks.append(drums) unit = drum_pipelines.DrumsExtractor(min_bars=1, gap_bars=1) self._unit_transform_test(unit, quantized_sequence, expected_drum_tracks)
def testExtractMelodiesMelodyTooLongWithPad(self): music_testing_lib.add_track_to_sequence(self.note_sequence, 0, [(12, 127, 2, 4), (14, 50, 6, 15)]) music_testing_lib.add_track_to_sequence(self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 6, 18)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) expected = [[ NO_EVENT, NO_EVENT, 12, NO_EVENT, NOTE_OFF, NO_EVENT, 14, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT, NO_EVENT ]] melodies, _ = melody_pipelines.extract_melodies( quantized_sequence, min_bars=1, max_steps_truncate=14, max_steps_discard=18, gap_bars=1, min_unique_pitches=2, ignore_polyphonic_notes=True, pad_end=True) melodies = [list(melody) for melody in melodies] self.assertEqual(expected, melodies)
def testFromQuantizedNoteSequenceNotCommonTimeSig(self): self.note_sequence.time_signatures[0].numerator = 7 self.note_sequence.time_signatures[0].denominator = 8 testing_lib.add_track_to_sequence(self.note_sequence, 0, [(12, 100, 0, 10), (11, 55, .25, .5), (40, 45, 2.5, 3.5), (30, 80, 2.5, 2.75), (55, 120, 4, 4.25), (52, 99, 4.75, 5)], is_drum=True) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) drums = drums_lib.DrumTrack() drums.from_quantized_sequence(quantized_sequence, search_start_step=0) expected = ([ DRUMS(12), DRUMS(11), NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, DRUMS(30, 40), NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, DRUMS(55), NO_DRUMS, NO_DRUMS, DRUMS(52) ]) self.assertEqual(expected, list(drums)) self.assertEqual(14, drums.steps_per_bar)
def testExtractMelodiesStatistics(self): music_testing_lib.add_track_to_sequence( self.note_sequence, 0, [(12, 100, 2, 4), (11, 1, 6, 7), (10, 100, 8, 10), (9, 100, 11, 14), (8, 100, 16, 40), (7, 100, 41, 42)]) music_testing_lib.add_track_to_sequence( self.note_sequence, 1, [(12, 127, 2, 4), (14, 50, 2, 8)]) music_testing_lib.add_track_to_sequence( self.note_sequence, 2, [(12, 127, 0, 1)]) music_testing_lib.add_track_to_sequence( self.note_sequence, 3, [(12, 127, 2, 4), (12, 50, 6, 8)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) _, stats = melody_pipelines.extract_melodies( quantized_sequence, min_bars=1, gap_bars=1, min_unique_pitches=2, ignore_polyphonic_notes=False) stats_dict = dict((stat.name, stat) for stat in stats) self.assertEqual(stats_dict['polyphonic_tracks_discarded'].count, 1) self.assertEqual(stats_dict['melodies_discarded_too_short'].count, 1) self.assertEqual(stats_dict['melodies_discarded_too_few_pitches'].count, 1) self.assertEqual( stats_dict['melody_lengths_in_bars'].counters, {float('-inf'): 0, 0: 0, 1: 0, 2: 0, 10: 1, 20: 0, 30: 0, 40: 0, 50: 0, 100: 0, 200: 0, 500: 0})
def testFromQuantizedNoteSequence(self): testing_lib.add_track_to_sequence(self.note_sequence, 0, [(60, 100, 0.0, 4.0), (64, 100, 0.0, 3.0), (67, 100, 1.0, 2.0)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=1) poly_seq = list(polyphony_lib.PolyphonicSequence(quantized_sequence)) pe = polyphony_lib.PolyphonicEvent expected_poly_seq = [ pe(pe.START, None), # step 0 pe(pe.NEW_NOTE, 64), pe(pe.NEW_NOTE, 60), pe(pe.STEP_END, None), # step 1 pe(pe.NEW_NOTE, 67), pe(pe.CONTINUED_NOTE, 64), pe(pe.CONTINUED_NOTE, 60), pe(pe.STEP_END, None), # step 2 pe(pe.CONTINUED_NOTE, 64), pe(pe.CONTINUED_NOTE, 60), pe(pe.STEP_END, None), # step 3 pe(pe.CONTINUED_NOTE, 60), pe(pe.STEP_END, None), pe(pe.END, None), ] self.assertEqual(expected_poly_seq, poly_seq)
def testFromQuantizedNoteSequenceMultipleTracks(self): testing_lib.add_track_to_sequence(self.note_sequence, 0, [(12, 100, 0, 10), (40, 45, 2.5, 3.5), (60, 100, 4, 5.5)], is_drum=True) testing_lib.add_track_to_sequence(self.note_sequence, 1, [(11, 55, .25, .5), (55, 120, 4, 4.25), (52, 99, 4.75, 5)], is_drum=True) testing_lib.add_track_to_sequence(self.note_sequence, 2, [(13, 100, 0, 10), (14, 45, 2.5, 3.5), (15, 100, 4, 5.5)]) quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, self.steps_per_quarter) drums = drums_lib.DrumTrack() drums.from_quantized_sequence(quantized_sequence, search_start_step=0) expected = ([ DRUMS(12), DRUMS(11), NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, DRUMS(40), NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, NO_DRUMS, DRUMS(55, 60), NO_DRUMS, NO_DRUMS, DRUMS(52) ]) self.assertEqual(expected, list(drums)) self.assertEqual(16, drums.steps_per_bar)
def testFromQuantizedNoteSequenceWithNoChords(self): 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] * 16 self.assertEqual(expected, list(chords))
def testFromNotesStepsPerBar(self): self.note_sequence.time_signatures[0].numerator = 7 self.note_sequence.time_signatures[0].denominator = 8 quantized_sequence = sequences_lib.quantize_note_sequence( self.note_sequence, steps_per_quarter=12) drums = drums_lib.DrumTrack() drums.from_quantized_sequence(quantized_sequence, search_start_step=0) self.assertEqual(42, drums.steps_per_bar)
def testExtractChords(self): music_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, _ = chord_pipelines.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))