--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+ "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+ <movement-title>Sonata No. 2</movement-title>\r
+ <identification>\r
+ <creator type="composer">Simon Bielman</creator>\r
+ <encoding>\r
+ <software>Finale 2007 for Windows</software>\r
+ <software>Dolet Light for Finale 2007</software>\r
+ <encoding-date>2008-08-20</encoding-date>\r
+ </encoding>\r
+ </identification>\r
+ <part-list>\r
+ <score-part id="P1">\r
+ <part-name>Piano</part-name>\r
+ <score-instrument id="P1-I1">\r
+ <instrument-name>Acoustic Grand Piano</instrument-name>\r
+ </score-instrument>\r
+ <midi-instrument id="P1-I1">\r
+ <midi-channel>1</midi-channel>\r
+ <midi-program>1</midi-program>\r
+ </midi-instrument>\r
+ </score-part>\r
+ </part-list>\r
+ <!--=========================================================-->\r
+ <part id="P1">\r
+ <measure number="25">\r
+ <attributes>\r
+ <divisions>336</divisions>\r
+ <key>\r
+ <fifths>0</fifths>\r
+ <mode>major</mode>\r
+ </key>\r
+ <time>\r
+ <beats>6</beats>\r
+ <beat-type>8</beat-type>\r
+ </time>\r
+ <staves>2</staves>\r
+ <clef number="1">\r
+ <sign>G</sign>\r
+ <line>2</line>\r
+ </clef>\r
+ <clef number="2">\r
+ <sign>F</sign>\r
+ <line>4</line>\r
+ </clef>\r
+ </attributes>\r
+ <note>\r
+ <pitch>\r
+ <step>E</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <duration>336</duration>\r
+ <voice>1</voice>\r
+ <type>quarter</type>\r
+ <stem>down</stem>\r
+ <staff>1</staff>\r
+ <notations>\r
+ <slur number="1" placement="above" type="start"/>\r
+ </notations>\r
+ </note>\r
+ <note>\r
+ <pitch>\r
+ <step>F</step>\r
+ <alter>1</alter>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <duration>84</duration>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <accidental>sharp</accidental>\r
+ <stem>down</stem>\r
+ <staff>1</staff>\r
+ <beam number="1">begin</beam>\r
+ <beam number="2">begin</beam>\r
+ </note>\r
+ <note>\r
+ <pitch>\r
+ <step>G</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <duration>84</duration>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>down</stem>\r
+ <staff>1</staff>\r
+ <beam number="1">end</beam>\r
+ <beam number="2">end</beam>\r
+ <notations>\r
+ <slur number="1" type="stop"/>\r
+ <ornaments>\r
+ <trill-mark default-y="39"/>\r
+ <wavy-line default-y="39" number="1" type="start"/>\r
+ </ornaments>\r
+ </notations>\r
+ </note>\r
+ <note>\r
+ <grace/>\r
+ <pitch>\r
+ <step>B</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ </note>\r
+ <note>\r
+ <pitch>\r
+ <step>A</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <duration>504</duration>\r
+ <voice>1</voice>\r
+ <type>quarter</type>\r
+ <dot/>\r
+ <stem>down</stem>\r
+ <staff>1</staff>\r
+ </note>\r
+ <note>\r
+ <grace/>\r
+ <pitch>\r
+ <step>G</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ <beam number="1">begin</beam>\r
+ <beam number="2">begin</beam>\r
+ </note>\r
+ <note>\r
+ <grace/>\r
+ <pitch>\r
+ <step>A</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ <beam number="1">end</beam>\r
+ <beam number="2">end</beam>\r
+ <notations>\r
+ <ornaments>\r
+ <wavy-line number="1" type="stop"/>\r
+ </ornaments>\r
+ </notations>\r
+ </note>\r
+ </measure>\r
+ </part>\r
+ <!--=========================================================-->\r
+</score-partwise>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+ "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+ <movement-title>Sonata No. 2</movement-title>\r
+ <identification>\r
+ <creator type="composer">Simon Bielman</creator>\r
+ <encoding>\r
+ <software>Finale 2007 for Windows</software>\r
+ <software>Dolet Light for Finale 2007</software>\r
+ <encoding-date>2008-08-20</encoding-date>\r
+ </encoding>\r
+ </identification>\r
+ <part-list>\r
+ <score-part id="P1">\r
+ <part-name>Piano</part-name>\r
+ <score-instrument id="P1-I1">\r
+ <instrument-name>Acoustic Grand Piano</instrument-name>\r
+ </score-instrument>\r
+ <midi-instrument id="P1-I1">\r
+ <midi-channel>1</midi-channel>\r
+ <midi-program>1</midi-program>\r
+ </midi-instrument>\r
+ </score-part>\r
+ </part-list>\r
+ <!--=========================================================-->\r
+ <part id="P1">\r
+ <measure number="25">\r
+ <attributes>\r
+ <divisions>32</divisions>\r
+ <key>\r
+ <fifths>0</fifths>\r
+ <mode>major</mode>\r
+ </key>\r
+ <time>\r
+ <beats>4</beats>\r
+ <beat-type>4</beat-type>\r
+ </time>\r
+ <clef>\r
+ <sign>G</sign>\r
+ <line>2</line>\r
+ </clef>\r
+ </attributes>\r
+ <note>\r
+ <pitch>\r
+ <step>E</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <duration>64</duration>\r
+ <voice>1</voice>\r
+ <type>half</type>\r
+ <stem>down</stem>\r
+ <staff>1</staff>\r
+ </note>\r
+ <note>\r
+ <grace steal-time-previous="20"/>\r
+ <pitch>\r
+ <step>G</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ </note>\r
+ <note>\r
+ <grace steal-time-next="20"/>\r
+ <pitch>\r
+ <step>A</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ </note>\r
+ <note>\r
+ <grace/>\r
+ <pitch>\r
+ <step>A</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ </note>\r
+ <note>\r
+ <pitch>\r
+ <step>E</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <duration>64</duration>\r
+ <voice>1</voice>\r
+ <type>half</type>\r
+ <stem>down</stem>\r
+ <staff>1</staff>\r
+ </note>\r
+ <note>\r
+ <grace/>\r
+ <pitch>\r
+ <step>G</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ <beam number="1">begin</beam>\r
+ <beam number="2">begin</beam>\r
+ </note>\r
+ <note>\r
+ <grace/>\r
+ <pitch>\r
+ <step>A</step>\r
+ <octave>5</octave>\r
+ </pitch>\r
+ <voice>1</voice>\r
+ <type>16th</type>\r
+ <stem>up</stem>\r
+ <staff>1</staff>\r
+ <beam number="1">end</beam>\r
+ <beam number="2">end</beam>\r
+ </note>\r
+ </measure>\r
+ </part>\r
+ <!--=========================================================-->\r
+</score-partwise>\r
class ChordEvent (NestedMusic):
def __init__ (self):
NestedMusic.__init__ (self)
+ self.after_grace_elements = None
self.grace_elements = None
self.grace_type = None
def append_grace (self, element):
if not self.grace_elements:
self.grace_elements = SequentialMusic ()
self.grace_elements.append (element)
+ def append_after_grace (self, element):
+ if element:
+ if not self.after_grace_elements:
+ self.after_grace_elements = SequentialMusic ()
+ self.after_grace_elements.append (element)
+
+ def has_elements (self):
+ return [e for e in self.elements if
+ isinstance (e, NoteEvent) or isinstance (e, RestEvent)] != []
+
def get_length (self):
l = Rational (0)
other_events = [e for e in self.elements if
not isinstance (e, RhythmicEvent)]
+ if self.after_grace_elements:
+ printer ('\\afterGrace {')
+
if self.grace_elements and self.elements:
if self.grace_type:
printer ('\\%s' % self.grace_type)
printer ('\\grace')
# don't print newlines after the { and } braces
self.grace_elements.print_ly (printer, False)
+ elif self.grace_elements: # no self.elements!
+ warning (_ ("Grace note with no following music: %s") % self.grace_elements)
+ if self.grace_type:
+ printer ('\\%s' % self.grace_type)
+ else:
+ printer ('\\grace')
+ self.grace_elements.print_ly (printer, False)
+ printer ('{}')
+
# Print all overrides and other settings needed by the
# articulations/ornaments before the note
for e in other_events:
for e in other_events:
e.print_after_note (printer)
+ if self.after_grace_elements:
+ printer ('}')
+ self.after_grace_elements.print_ly (printer, False)
+
self.print_comment (printer)
class Partial (Music):
def __init__ (self):
Measure_element.__init__ (self)
self.instrument_name = ''
-
+ self._after_grace = False
+ def is_grace (self):
+ return self.get_maybe_exist_named_child (u'grace')
+ def is_after_grace (self):
+ if not self.is_grace():
+ return False;
+ gr = self.get_maybe_exist_typed_child (Grace)
+ return self._after_grace or hasattr (gr, 'steal-time-previous');
+
def get_duration_log (self):
ch = self.get_maybe_exist_named_child (u'type')
measure_start_moment = now
is_first_measure = True
previous_measure = None
+ # Graces at the end of a measure need to have their position set to the
+ # previous number!
+ pending_graces = []
for m in measures:
# implicit measures are used for artificial measures, e.g. when
# a repeat bar line splits a bar into two halves. In this case,
if n.get_name() == 'backup':
dur = - dur
+ # reset all graces before the backup to after-graces:
+ for n in pending_graces:
+ n._when = n._prev_when
+ n._measure_position = n._prev_measure_position
+ n._after_grace = True
+ pending_graces = []
if n.get_maybe_exist_typed_child (Grace):
dur = Rational (0)
n._when = now
n._measure_position = measure_position
+
+ # For all grace notes, store the previous note, in case need
+ # to turn the grace note into an after-grace later on!
+ if isinstance(n, Note) and n.is_grace ():
+ n._prev_when = last_moment
+ n._prev_measure_position = last_measure_position
+ # After-graces are placed at the same position as the previous note
+ if isinstance(n, Note) and n.is_after_grace ():
+ # TODO: We should do the same for grace notes at the end of
+ # a measure with no following note!!!
+ n._when = last_moment
+ n._measure_position = last_measure_position
+ elif isinstance(n, Note) and n.is_grace ():
+ pending_graces.append (n)
+ elif (dur > Rational (0)):
+ pending_graces = [];
+
n._duration = dur
if dur > Rational (0):
last_moment = now
if instrument:
n.instrument_name = part_list.get_instrument (instrument.id)
+ # reset all graces at the end of the measure to after-graces:
+ for n in pending_graces:
+ n._when = n._prev_when
+ n._measure_position = n._prev_measure_position
+ n._after_grace = True
+ pending_graces = []
# Incomplete first measures are not padded, but registered as partial
if is_first_measure:
is_first_measure = False
if a:
voice_builder.add_partial (a)
continue
+
is_chord = n.get_maybe_exist_named_child ('chord')
- if not is_chord:
+ is_after_grace = (isinstance (n, musicxml.Note) and n.is_after_grace ());
+ if not is_chord and not is_after_grace:
try:
voice_builder.jumpto (n._when)
except NegativeSkip, neg:
ev_chord = musicexp.ChordEvent()
voice_builder.add_music (ev_chord, n._duration)
+ # For grace notes:
grace = n.get_maybe_exist_typed_child (musicxml.Grace)
- if grace:
+ if n.is_grace ():
+ is_after_grace = ev_chord.has_elements () or n.is_after_grace ();
+ is_chord = n.get_maybe_exist_typed_child (musicxml.Chord)
+
grace_chord = None
- if n.get_maybe_exist_typed_child (musicxml.Chord) and ev_chord.grace_elements:
- grace_chord = ev_chord.grace_elements.get_last_event_chord ()
- if not grace_chord:
- grace_chord = musicexp.ChordEvent ()
- ev_chord.append_grace (grace_chord)
- if hasattr (grace, 'slash'):
+
+ # after-graces and other graces use different lists; Depending on
+ # whether we have a chord or not, obtain either a new ChordEvent or
+ # the previous one to create a chord
+ if is_after_grace:
+ if ev_chord.after_grace_elements and n.get_maybe_exist_typed_child (musicxml.Chord):
+ grace_chord = ev_chord.after_grace_elements.get_last_event_chord ()
+ if not grace_chord:
+ grace_chord = musicexp.ChordEvent ()
+ ev_chord.append_after_grace (grace_chord)
+ elif n.is_grace ():
+ if ev_chord.grace_elements and n.get_maybe_exist_typed_child (musicxml.Chord):
+ grace_chord = ev_chord.grace_elements.get_last_event_chord ()
+ if not grace_chord:
+ grace_chord = musicexp.ChordEvent ()
+ ev_chord.append_grace (grace_chord)
+
+ if hasattr (grace, 'slash') and not is_after_grace:
# TODO: use grace_type = "appoggiatura" for slurred grace notes
if grace.slash == "yes":
ev_chord.grace_type = "acciaccatura"
frac = (1,1)
if mod:
frac = mod.get_fraction ()
-
+
tuplet_events.append ((ev_chord, tuplet_event, frac))
# First, close all open slurs, only then start any new slur
for a in ornaments:
for ch in a.get_all_children ():
ev = musicxml_articulation_to_lily_event (ch)
- if ev:
+ if ev:
ev_chord.append (ev)
dynamics = notations.get_named_children ('dynamics')