--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="2.0">
+ <identification>
+ <miscellaneous>
+ <miscellaneous-field name="description">There can be multiple subsequent
+ harmony elements, indicating a harmony change during a note</miscellaneous-field>
+ </miscellaneous>
+ </identification>
+ <part-list>
+ <score-part id="P1">
+ <part-name>MusicXML Part</part-name>
+ </score-part>
+ </part-list>
+ <!--=========================================================-->
+ <part id="P1">
+ <measure number="1">
+ <attributes>
+ <divisions>480</divisions>
+ <key>
+ <fifths>0</fifths>
+ <mode>major</mode>
+ </key>
+ <time>
+ <beats>4</beats>
+ <beat-type>4</beat-type>
+ </time>
+ <clef>
+ <sign>G</sign>
+ <line>2</line>
+ </clef>
+ </attributes>
+ <harmony print-frame="no">
+ <root>
+ <root-step>C</root-step>
+ </root>
+ <kind text="">major</kind>
+ </harmony>
+ <harmony print-frame="no">
+ <root>
+ <root-step>F</root-step>
+ <root-alter>1</root-alter>
+ </root>
+ <kind text="m6">minor-sixth</kind>
+ </harmony>
+ <note>
+ <pitch>
+ <step>A</step>
+ <octave>4</octave>
+ </pitch>
+ <duration>960</duration>
+ <voice>1</voice>
+ <type>half</type>
+ </note>
+ <harmony print-frame="no">
+ <root>
+ <root-step>D</root-step>
+ </root>
+ <kind text="m7">minor-seventh</kind>
+ </harmony>
+ <harmony print-frame="no">
+ <root>
+ <root-step>G</root-step>
+ </root>
+ <kind text="7">dominant</kind>
+ </harmony>
+ <note>
+ <pitch>
+ <step>G</step>
+ <octave>4</octave>
+ </pitch>
+ <duration>960</duration>
+ <voice>1</voice>
+ <type>half</type>
+ </note>
+ </measure>
+ </part>
+</score-partwise>
def current_duration (self):
return self.end_moment - self.begin_moment
- def add_music (self, music, duration):
+ def add_music (self, music, duration, relevant = True):
assert isinstance (music, musicexp.Music)
if self.pending_multibar > Rational (0):
self._insert_multibar ()
- self.has_relevant_elements = True
+ self.has_relevant_elements = self.has_relevant_elements or relevant
self.elements.append (music)
self.begin_moment = self.end_moment
self.set_duration (duration)
self.pending_dynamics = []
# Insert some music command that does not affect the position in the measure
- def add_command (self, command):
+ def add_command (self, command, relevant = True):
assert isinstance (command, musicexp.Music)
if self.pending_multibar > Rational (0):
self._insert_multibar ()
- self.has_relevant_elements = True
+ self.has_relevant_elements = self.has_relevant_elements or relevant
self.elements.append (command)
- def add_barline (self, barline):
- # TODO: Implement merging of default barline and custom bar line
- self.add_music (barline, Rational (0))
+ def add_barline (self, barline, relevant = False):
+ # Insert only if we don't have a barline already
+ # TODO: Implement proper merging of default barline and custom bar line
+ has_relevant = self.has_relevant_elements
+ if (not (self.elements) or
+ not (isinstance (self.elements[-1], musicexp.BarLine)) or
+ (self.pending_multibar > Rational (0))):
+ self.add_music (barline, Rational (0))
+ self.has_relevant_elements = has_relevant or relevant
def add_partial (self, command):
self.ignore_skips = True
+ # insert the partial, but restore relevant_elements (partial is not relevant)
+ relevant = self.has_relevant_elements
self.add_command (command)
+ self.has_relevant_elements = relevant
def add_dynamics (self, dynamic):
# store the dynamic item(s) until we encounter the next note/rest:
def add_bar_check (self, number):
# re/store has_relevant_elements, so that a barline alone does not
# trigger output for figured bass, chord names
- has_relevant = self.has_relevant_elements
b = musicexp.BarLine ()
b.bar_number = number
self.add_barline (b)
- self.has_relevant_elements = has_relevant
def jumpto (self, moment):
current_end = self.end_moment + self.pending_multibar
evc = musicexp.ChordEvent ()
evc.elements.append (skip)
- self.add_music (evc, diff)
+ self.add_music (evc, diff, False)
if diff > Rational (0) and moment == 0:
self.ignore_skips = False
a = musicxml_partial_to_lily (n.partial)
if a:
voice_builder.add_partial (a)
+ figured_bass_builder.add_partial (a)
+ chordnames_builder.add_partial (a)
continue
is_chord = n.get_maybe_exist_named_child ('chord')
if not is_chord and not is_after_grace:
try:
voice_builder.jumpto (n._when)
+ figured_bass_builder.jumpto (n._when)
+ chordnames_builder.jumpto (n._when)
except NegativeSkip, neg:
voice_builder.correct_negative_skip (n._when)
+ figured_bass_builder.correct_negative_skip (n._when)
+ chordnames_builder.correct_negative_skip (n._when)
n.message (_ ("Negative skip found: from %s to %s, difference is %s") % (neg.here, neg.dest, neg.dest - neg.here))
if isinstance (n, musicxml.Barline):
for a in barlines:
if isinstance (a, musicexp.BarLine):
voice_builder.add_barline (a)
+ figured_bass_builder.add_barline (a, False)
+ chordnames_builder.add_barline (a, False)
elif isinstance (a, RepeatMarker) or isinstance (a, EndingMarker):
voice_builder.add_command (a)
+ figured_bass_builder.add_barline (a, False)
+ chordnames_builder.add_barline (a, False)
continue
# Continue any multimeasure-rests before trying to add bar checks!
# create \figuremode { figured bass elements }
if figured_bass_builder.has_relevant_elements:
fbass_music = musicexp.SequentialMusic ()
- fbass_music.elements = figured_bass_builder.elements
+ fbass_music.elements = group_repeats (figured_bass_builder.elements)
v = musicexp.ModeChangingMusicWrapper()
v.mode = 'figuremode'
v.element = fbass_music
# create \chordmode { chords }
if chordnames_builder.has_relevant_elements:
cname_music = musicexp.SequentialMusic ()
- cname_music.elements = chordnames_builder.elements
+ cname_music.elements = group_repeats (chordnames_builder.elements)
v = musicexp.ModeChangingMusicWrapper()
v.mode = 'chordmode'
v.element = cname_music