Skip to content

Commit

Permalink
Parse music title and composers from MusicXML.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 706509803
  • Loading branch information
irolnick authored and Magenta Team committed Dec 18, 2024
1 parent b16a27f commit 5142ee3
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
16 changes: 16 additions & 0 deletions note_seq/musicxml_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,22 @@ def _get_score(filename):

def _parse(self):
"""Parse the uncompressed MusicXML document."""
# Parse work title and creators
xml_work = self._score.find('work')
self.work_title = (
getattr(xml_work.find('work-title'), 'text', '')
if xml_work is not None
else ''
)
self.creators = []
xml_identification = self._score.find('identification')
if xml_identification is not None:
self.creators = [
creator.text
for creator in xml_identification.findall('creator')
if creator.text
]

# Parse part-list
xml_part_list = self._score.find('part-list')
if xml_part_list is not None:
Expand Down
26 changes: 26 additions & 0 deletions note_seq/musicxml_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,32 @@ def test_invalid_note_type(self):
with self.assertRaises(musicxml_parser.InvalidNoteDurationTypeError):
musicxml_parser.MusicXMLDocument(temp_file.name)

def test_work_title(self):
"""Verify that the work/work-title element is parsed."""

xml = rb"""<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE score-partwise PUBLIC
"-//Recordare//DTD MusicXML 3.0 Partwise//EN"
"http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.0">
<work>
<work-title>My Funny Valentine</work-title>
</work>
<identification>
<creator type="composer">Richard Rodgers</creator>
<creator type="composer">Lorenz Hart</creator>
</identification>
</score-partwise>
"""
with tempfile.NamedTemporaryFile() as temp_file:
temp_file.write(xml)
temp_file.flush()
ns = musicxml_reader.musicxml_file_to_sequence_proto(temp_file.name)

self.assertEqual(ns.sequence_metadata.title, 'My Funny Valentine')
self.assertEqual(ns.sequence_metadata.composers,
['Richard Rodgers', 'Lorenz Hart'])


if __name__ == '__main__':
absltest.main()
6 changes: 6 additions & 0 deletions note_seq/musicxml_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ class MusicXMLDocument
# Populate header.
sequence.ticks_per_quarter = musicxml_document.midi_resolution

# Populate work title and creators.
if musicxml_document.work_title:
sequence.sequence_metadata.title = musicxml_document.work_title
for creator in musicxml_document.creators:
sequence.sequence_metadata.composers.append(creator)

# Populate time signatures.
musicxml_time_signatures = musicxml_document.get_time_signatures()
for musicxml_time_signature in musicxml_time_signatures:
Expand Down

0 comments on commit 5142ee3

Please sign in to comment.