def compare_directory(directory): files_in_dir = tf.gfile.ListDirectory(directory) for file_in_dir in files_in_dir: if not file_in_dir.endswith('.abc'): continue abc = os.path.join(directory, file_in_dir) midis = {} ref_num = 1 while True: midi = re.sub(r'\.abc$', str(ref_num) + '.mid', os.path.join(directory, file_in_dir)) if not tf.gfile.Exists(midi): break midis[ref_num] = midi ref_num += 1 print('parsing {}'.format(abc)) tunes, exceptions = abc_parser.parse_tunebook_file(abc) if len(tunes) != len(midis) - len(exceptions): raise ValueError( 'Different number of tunes and midis for {}'.format(abc)) for tune in tunes.values(): expanded_tune = sequences_lib.expand_section_groups(tune) midi_ns = midi_io.midi_file_to_sequence_proto( midis[tune.reference_number]) # abc2midi adds a 1-tick delay to the start of every note, but we don't. tick_length = ((1 / (midi_ns.tempos[0].qpm / 60)) / midi_ns.ticks_per_quarter) for note in midi_ns.notes: note.start_time -= tick_length if len(midi_ns.notes) != len(expanded_tune.notes): pdb.set_trace()
def testExpandSectionGroups(self): sequence = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence( sequence, 0, [(60, 100, 0.0, 1.0), (72, 100, 1.0, 2.0), (59, 100, 2.0, 3.0), (71, 100, 3.0, 4.0)]) sequence.section_annotations.add(time=0, section_id=0) sequence.section_annotations.add(time=1, section_id=1) sequence.section_annotations.add(time=2, section_id=2) sequence.section_annotations.add(time=3, section_id=3) # A((BC)2D)2 sg = sequence.section_groups.add() sg.sections.add(section_id=0) sg.num_times = 1 sg = sequence.section_groups.add() sg.sections.add(section_group=music_pb2.NoteSequence.SectionGroup( sections=[music_pb2.NoteSequence.Section(section_id=1), music_pb2.NoteSequence.Section(section_id=2)], num_times=2)) sg.sections.add(section_id=3) sg.num_times = 2 expanded = sequences_lib.expand_section_groups(sequence) expected = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence( expected, 0, [(60, 100, 0.0, 1.0), (72, 100, 1.0, 2.0), (59, 100, 2.0, 3.0), (72, 100, 3.0, 4.0), (59, 100, 4.0, 5.0), (71, 100, 5.0, 6.0), (72, 100, 6.0, 7.0), (59, 100, 7.0, 8.0), (72, 100, 8.0, 9.0), (59, 100, 9.0, 10.0), (71, 100, 10.0, 11.0)]) expected.section_annotations.add(time=0, section_id=0) expected.section_annotations.add(time=1, section_id=1) expected.section_annotations.add(time=2, section_id=2) expected.section_annotations.add(time=3, section_id=1) expected.section_annotations.add(time=4, section_id=2) expected.section_annotations.add(time=5, section_id=3) expected.section_annotations.add(time=6, section_id=1) expected.section_annotations.add(time=7, section_id=2) expected.section_annotations.add(time=8, section_id=1) expected.section_annotations.add(time=9, section_id=2) expected.section_annotations.add(time=10, section_id=3) self.assertProtoEquals(expected, expanded)
def testExpandWithoutSectionGroups(self): sequence = copy.copy(self.note_sequence) testing_lib.add_track_to_sequence( sequence, 0, [(60, 100, 0.0, 1.0), (72, 100, 1.0, 2.0), (59, 100, 2.0, 3.0), (71, 100, 3.0, 4.0)]) sequence.section_annotations.add(time=0, section_id=0) sequence.section_annotations.add(time=1, section_id=1) sequence.section_annotations.add(time=2, section_id=2) sequence.section_annotations.add(time=3, section_id=3) expanded = sequences_lib.expand_section_groups(sequence) self.assertEqual(sequence, expanded)
def compare_directory(self, directory): self.maxDiff = None # pylint: disable=invalid-name files_in_dir = tf.gfile.ListDirectory(directory) files_parsed = 0 for file_in_dir in files_in_dir: if not file_in_dir.endswith('.abc'): continue abc = os.path.join(directory, file_in_dir) midis = {} ref_num = 1 while True: midi = re.sub(r'\.abc$', str(ref_num) + '.mid', os.path.join(directory, file_in_dir)) if not tf.gfile.Exists(midi): break midis[ref_num] = midi ref_num += 1 print('parsing {}: {}'.format(files_parsed, abc)) tunes, exceptions = abc_parser.parse_abc_tunebook_file(abc) files_parsed += 1 self.assertEqual(len(tunes), len(midis) - len(exceptions)) for tune in tunes.values(): expanded_tune = sequences_lib.expand_section_groups(tune) midi_ns = midi_io.midi_file_to_sequence_proto( midis[tune.reference_number]) # abc2midi adds a 1-tick delay to the start of every note, but we don't. tick_length = ((1 / (midi_ns.tempos[0].qpm / 60)) / midi_ns.ticks_per_quarter) for note in midi_ns.notes: note.start_time -= tick_length # For now, don't compare velocities. note.velocity = 90 if len(midi_ns.notes) != len(expanded_tune.notes): pdb.set_trace() self.assertProtoEquals(midi_ns, expanded_tune) for midi_note, test_note in zip(midi_ns.notes, expanded_tune.notes): try: self.assertProtoEquals(midi_note, test_note) except Exception as e: # pylint: disable=broad-except print(e) pdb.set_trace() self.assertEqual(midi_ns.total_time, expanded_tune.total_time)
def compareToAbc2midiAndMetadata(self, midi_path, expected_metadata, expected_expanded_metadata, test): """Compare parsing results to the abc2midi "reference" implementation.""" # Compare section annotations and groups before expanding. self.compareProtoList(expected_metadata.section_annotations, test.section_annotations) self.compareProtoList(expected_metadata.section_groups, test.section_groups) expanded_test = sequences_lib.expand_section_groups(test) abc2midi = midi_io.midi_file_to_sequence_proto( os.path.join(tf.resource_loader.get_data_files_path(), midi_path)) # abc2midi adds a 1-tick delay to the start of every note, but we don't. tick_length = ((1 / (abc2midi.tempos[0].qpm / 60)) / abc2midi.ticks_per_quarter) for note in abc2midi.notes: note.start_time -= tick_length self.assertEqual(len(abc2midi.notes), len(expanded_test.notes)) for exp_note, test_note in zip(abc2midi.notes, expanded_test.notes): # For now, don't compare velocities. exp_note.velocity = test_note.velocity self.assertProtoEquals(exp_note, test_note) self.assertEqual(abc2midi.total_time, expanded_test.total_time) self.compareProtoList(abc2midi.time_signatures, expanded_test.time_signatures) # We've checked the notes and time signatures, now compare the rest of the # proto to the expected proto. expanded_test_copy = copy.deepcopy(expanded_test) del expanded_test_copy.notes[:] expanded_test_copy.ClearField('total_time') del expanded_test_copy.time_signatures[:] self.assertProtoEquals(expected_expanded_metadata, expanded_test_copy)
def compareToAbc2midiAndMetadata(self, midi_path, expected_metadata, expected_expanded_metadata, test): """Compare parsing results to the abc2midi "reference" implementation.""" # Compare section annotations and groups before expanding. self.compareProtoList(expected_metadata.section_annotations, test.section_annotations) self.compareProtoList(expected_metadata.section_groups, test.section_groups) expanded_test = sequences_lib.expand_section_groups(test) abc2midi = midi_io.midi_file_to_sequence_proto( os.path.join(tf.resource_loader.get_data_files_path(), midi_path)) # abc2midi adds a 1-tick delay to the start of every note, but we don't. tick_length = ((1 / (abc2midi.tempos[0].qpm / 60)) / abc2midi.ticks_per_quarter) for note in abc2midi.notes: # For now, don't compare velocities. note.velocity = 90 note.start_time -= tick_length self.compareProtoList(abc2midi.notes, expanded_test.notes) self.assertEqual(abc2midi.total_time, expanded_test.total_time) self.compareProtoList(abc2midi.time_signatures, expanded_test.time_signatures) # We've checked the notes and time signatures, now compare the rest of the # proto to the expected proto. expanded_test_copy = copy.deepcopy(expanded_test) del expanded_test_copy.notes[:] expanded_test_copy.ClearField('total_time') del expanded_test_copy.time_signatures[:] self.assertProtoEquals(expected_expanded_metadata, expanded_test_copy)