def testDummy(self): # Create a single staff, and a single vertical which is the correct height # of a stem. The vertical has x = 20 and goes from struct = structure.Structure( staff_detector=staves_base.ComputedStaves( staves=[[[10, 50], [90, 50]]], staffline_distance=[12], staffline_thickness=2, staves_interpolated_y=[[50] * 100]), beams=beams.ComputedBeams(np.zeros((0, 2, 2))), verticals=verticals.ComputedVerticals( lines=[[[20, 38], [20, 38 + 12 * 4]]]), connected_components=components.ComputedComponents([])) stems = stems_module.Stems(struct) # Create a Page with Glyphs. input_page = musicscore_pb2.Page(system=[ musicscore_pb2.StaffSystem(staff=[ musicscore_pb2.Staff( staffline_distance=12, center_line=[ musicscore_pb2.Point(x=10, y=50), musicscore_pb2.Point(x=90, y=50) ], glyph=[ # Cannot have a stem because it's a flat. musicscore_pb2.Glyph(type=musicscore_pb2.Glyph.FLAT, x=15, y_position=-1), # On the right side of the stem, the correct distance away. musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_FILLED, x=25, y_position=-1), # Too high for the stem. musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_FILLED, x=25, y_position=4), # Too far right from the stem. musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_FILLED, x=35, y_position=-1), ]) ]) ]) page = stems.apply(input_page) self.assertFalse(page.system[0].staff[0].glyph[0].HasField("stem")) self.assertTrue(page.system[0].staff[0].glyph[1].HasField("stem")) self.assertEqual( page.system[0].staff[0].glyph[1].stem, musicscore_pb2.LineSegment(start=Point(x=20, y=38), end=Point(x=20, y=38 + 12 * 4))) self.assertFalse(page.system[0].staff[0].glyph[2].HasField("stem")) self.assertFalse(page.system[0].staff[0].glyph[3].HasField("stem"))
def create_glyph(glyph): return musicscore_pb2.Glyph( x=glyph[GlyphsTensorColumns.X], y_position=glyph[GlyphsTensorColumns.Y_POSITION], type=glyph[GlyphsTensorColumns.TYPE])
def testSmallScore(self): score = musicscore_pb2.Score(page=[ musicscore_pb2.Page(system=[ musicscore_pb2.StaffSystem(staff=[ musicscore_pb2.Staff(glyph=[ musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_FILLED, x=10, y_position=0, note=music_pb2.NoteSequence.Note( start_time=0, end_time=1, pitch=71)), musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_EMPTY, x=110, y_position=-6, note=music_pb2.NoteSequence.Note( start_time=1, end_time=2.5, pitch=61)), ]), musicscore_pb2.Staff(glyph=[ musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_WHOLE, x=10, y_position=2, note=music_pb2.NoteSequence.Note( start_time=0, end_time=4, pitch=50)), musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_FILLED, beam=[ musicscore_pb2.LineSegment(), musicscore_pb2.LineSegment() ], x=110, y_position=-4, note=music_pb2.NoteSequence.Note( start_time=4, end_time=4.25, pitch=60)), ]), ]), ]), ]) self.assertEqual( b"""<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd"> <score-partwise version="3.0"> <part-list> <score-part id="P1"> <part-name>Part 1</part-name> </score-part> <score-part id="P2"> <part-name>Part 2</part-name> </score-part> </part-list> <part id="P1"> <measure number="1"> <attributes> <divisions>1024</divisions> <time symbol="common"> <beats>4</beats> <beat-type>4</beat-type> </time> </attributes> <note> <voice>1</voice> <type>quarter</type> <duration>1024</duration> <pitch> <step>B</step> <alter>0</alter> <octave>4</octave> </pitch> </note> <note> <voice>1</voice> <type>half</type> <duration>1536</duration> <pitch> <step>C</step> <alter>1</alter> <octave>4</octave> </pitch> </note> </measure> </part> <part id="P2"> <measure number="1"> <attributes> <divisions>1024</divisions> <time symbol="common"> <beats>4</beats> <beat-type>4</beat-type> </time> </attributes> <note> <voice>1</voice> <type>whole</type> <duration>4096</duration> <pitch> <step>D</step> <alter>0</alter> <octave>3</octave> </pitch> </note> <note> <voice>1</voice> <type>16th</type> <duration>256</duration> <pitch> <step>C</step> <alter>0</alter> <octave>4</octave> </pitch> </note> </measure> </part> </score-partwise> """, musicxml.score_to_musicxml(score))
from moonlight.protobuf import musicscore_pb2 # Sample glyph predictions. # Shape (num_staves, num_stafflines, width). PREDICTIONS = np.asarray( [[[1, 1, 1, 1, 2, 1], [3, 1, 5, 1, 1, 1], [1, 4, 1, 1, 1, 1]], [[1, 1, 3, 1, 1, 1], [1, 1, 5, 1, 1, 1], [1, 1, 1, 1, 3, 5]]]) # pyformat: disable # Page corresponding to the glyphs in PREDICTIONS. GLYPHS_PAGE = musicscore_pb2.Page(system=[ musicscore_pb2.StaffSystem(staff=[ musicscore_pb2.Staff(glyph=[ musicscore_pb2.Glyph(x=0, y_position=0, type=3), musicscore_pb2.Glyph(x=1, y_position=-1, type=4), musicscore_pb2.Glyph(x=2, y_position=0, type=5), musicscore_pb2.Glyph(x=4, y_position=1, type=2), ]), musicscore_pb2.Staff(glyph=[ musicscore_pb2.Glyph(x=2, y_position=1, type=3), musicscore_pb2.Glyph(x=2, y_position=0, type=5), musicscore_pb2.Glyph(x=4, y_position=-1, type=3), musicscore_pb2.Glyph(x=5, y_position=-1, type=5), ]), ]), ]) class DummyGlyphClassifier(convolutional.Convolutional1DGlyphClassifier):
def testDummy(self): # Create a single staff, and a single vertical which is the correct height # of a stem. The vertical has x = 20 and goes from struct = structure.Structure( staff_detector=staves_base.ComputedStaves( staves=[[[10, 50], [90, 50]], [[11, 150], [91, 150]], [[10, 250], [90, 250]], [[10, 350], [90, 350]]], staffline_distance=[12] * 4, staffline_thickness=2, staves_interpolated_y=[[50] * 100, [150] * 100, [250] * 100, [350] * 100]), beams=beams.ComputedBeams(np.zeros((0, 2, 2))), connected_components=components.ComputedComponents(np.zeros( (0, 5))), verticals=verticals.ComputedVerticals(lines=[ # Joins the first 2 staves. [[10, 50 - 12 * 2], [10, 150 + 12 * 2]], # Another barline, too close to the first one. [[12, 50 - 12 * 2], [12, 150 + 12 * 2]], # This barline is far enough, because the second barline was # skipped. [[13, 50 - 12 * 2], [13, 150 + 12 * 2]], # Single staff barlines are skipped. [[30, 50 - 12 * 2], [30, 50 + 12 * 2]], [[31, 150 - 12 * 2], [31, 150 + 12 * 2]], # Too close to a stem. [[70, 50 - 12 * 2], [70, 50 + 12 * 2]], # Too short. [[90, 50 - 12 * 2], [90, 50 + 12 * 2]], # Another barline which is kept. [[90, 50 - 12 * 2], [90, 150 + 12 * 2]], # Staff 1 has no barlines. # Staff 2 has 2 barlines. [[11, 350 - 12 * 2], [11, 350 + 12 * 2]], [[90, 350 - 12 * 2], [90, 350 + 12 * 2]], ])) barlines = barlines_module.Barlines(struct, close_barline_threshold=3) # Create a Page with Glyphs. input_page = musicscore_pb2.Page(system=[ musicscore_pb2.StaffSystem(staff=[ musicscore_pb2.Staff( staffline_distance=12, center_line=[ musicscore_pb2.Point(x=10, y=50), musicscore_pb2.Point(x=90, y=50) ], glyph=[ # Stem is close to the last vertical on the first staff, so # a barline will not be detected there. musicscore_pb2.Glyph( type=musicscore_pb2.Glyph.NOTEHEAD_FILLED, x=60, y_position=2, stem=musicscore_pb2.LineSegment( start=musicscore_pb2.Point(x=72, y=40), end=musicscore_pb2.Point(x=72, y=80))), ]), musicscore_pb2.Staff(staffline_distance=12, center_line=[ musicscore_pb2.Point(x=10, y=150), musicscore_pb2.Point(x=90, y=150) ]), musicscore_pb2.Staff(staffline_distance=12, center_line=[ musicscore_pb2.Point(x=10, y=250), musicscore_pb2.Point(x=90, y=250) ]), musicscore_pb2.Staff(staffline_distance=12, center_line=[ musicscore_pb2.Point(x=10, y=350), musicscore_pb2.Point(x=90, y=350) ]), ]) ]) page = barlines.apply(input_page) self.assertEqual(3, len(page.system)) self.assertEqual(2, len(page.system[0].staff)) self.assertItemsEqual([10, 13, 90], (bar.x for bar in page.system[0].bar)) self.assertEqual(1, len(page.system[1].staff)) self.assertEqual(0, len(page.system[1].bar)) self.assertEqual(1, len(page.system[2].staff)) self.assertEqual(2, len(page.system[2].bar)) self.assertItemsEqual([11, 90], (bar.x for bar in page.system[2].bar))