Tone Generation
ci / checks (push) Has been cancelled

This commit is contained in:
khodowany
2026-09-18 01:17:36 -05:00
parent 64eac2f11e
commit 80873a0896
39 changed files with 1624 additions and 52 deletions
+16 -2
View File
@@ -138,6 +138,8 @@ def write_note(parent, event: dict, voice: str, divisions: int, tuplets: list[di
element(item, 'octave', pitch['octave'] if pitch else 4)
if not event.get('grace'):
element(node, 'duration', int(fraction(pitch['duration'] if pitch else event['duration']) * divisions))
for marker in (pitch or {}).get('sound_ties', []):
element(node, 'tie', type=marker['type'], time_only=','.join(map(str, marker['passes'])) if marker.get('passes') else None)
for field, action in (('tie_from', 'stop'), ('tie_to', 'start')):
if pitch and pitch.get(field):
element(node, 'tie', type=action)
@@ -170,6 +172,8 @@ def write_note(parent, event: dict, voice: str, divisions: int, tuplets: list[di
for beam in event.get('beams', []):
element(node, 'beam', beam['type'], number=beam['level'])
notations = element(node, 'notations')
for action in (pitch or {}).get('printed_ties', []):
element(notations, 'tied', type=action)
for field, action in (('tie_from', 'stop'), ('tie_to', 'start')):
if pitch and pitch.get(field):
element(notations, 'tied', type=action)
@@ -202,6 +206,16 @@ def write_note(parent, event: dict, voice: str, divisions: int, tuplets: list[di
for syllable in verse['syllables']:
element(lyric, syllable['kind'], syllable['text'], **syllable['attributes'])
def write_barline(bar, measure, location):
if not any(location in measure.get(field, {}) for field in ('barlines', 'repeats', 'endings')):
return
node = element(bar, 'barline', location=location)
element(node, 'bar-style', measure.get('barlines', {}).get(location, 'regular'))
if ending := measure.get('endings', {}).get(location):
element(node, 'ending', ending.get('text', ''), number=','.join(map(str, ending['numbers'])), type=ending['type'], print_object='yes' if ending.get('visible', True) else 'no')
if repeat := measure.get('repeats', {}).get(location):
element(node, 'repeat', direction=repeat['direction'], times=repeat.get('times'))
def musicxml_tree(document: dict) -> ElementTree.ElementTree:
validate_document(document)
root = ElementTree.Element('score-partwise', {'version': '4.0'})
@@ -245,6 +259,7 @@ def musicxml_tree(document: dict) -> ElementTree.ElementTree:
previous_state = {}
for index, measure in enumerate(staff['measures']):
bar = element(part, 'measure', number=index + 1, implicit='yes' if measure['implicit'] else 'no')
write_barline(bar, measure, 'left')
times = [fraction(measure['duration'])]
times.extend(fraction(n[field]) for v in measure['voices'] for n in v['notes'] for field in ('onset', 'duration'))
times.extend(fraction(p['duration']) for v in measure['voices'] for n in v['notes'] for p in n['pitches'])
@@ -303,8 +318,7 @@ def musicxml_tree(document: dict) -> ElementTree.ElementTree:
if cursor < fraction(measure['duration']):
element(element(bar, 'forward'), 'duration', int((fraction(measure['duration']) - cursor) * divisions))
cursor = fraction(measure['duration'])
for location, style in measure.get('barlines', {}).items():
element(element(bar, 'barline', location=location), 'bar-style', style)
write_barline(bar, measure, 'right')
absolute += fraction(measure['duration'])
return ElementTree.ElementTree(root)