From 8de0c0e819512b7b2cb3a8cf53ce359cc3256110 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer Date: Wed, 12 Nov 2008 00:13:25 +0100 Subject: [PATCH] MusicXML: Correctly handle bar checks with attributes and MM rests -) Put the bar line BEFORE the attribute -) Add Bar checks around MM rests (of course not inside MM rests!) -) If we have a MM rest, globally set Score.skipBars=##t -) Don't print a bar check at the very beginning of a score --- python/musicxml.py | 17 +++++++++++-- scripts/musicxml2ly.py | 55 +++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/python/musicxml.py b/python/musicxml.py index a7cf59730f..53dd4283d5 100644 --- a/python/musicxml.py +++ b/python/musicxml.py @@ -259,15 +259,27 @@ class Measure_element (Music_xml_node): return None def is_first (self): - cn = self._parent.get_typed_children (self.__class__) - cn = [c for c in cn if c.get_voice_id () == self.get_voice_id ()] + # Look at all measure elements (previously we had self.__class__, which + # only looked at objects of the same type! + cn = self._parent.get_typed_children (Measure_element) + # But only look at the correct voice; But include Attributes, too, which + # are not tied to any particular voice + cn = [c for c in cn if (c.get_voice_id () == self.get_voice_id ()) or isinstance (c, Attributes)] return cn[0] == self class Attributes (Measure_element): def __init__ (self): Measure_element.__init__ (self) self._dict = {} + self._original_tag = None + def is_first (self): + cn = self._parent.get_typed_children (self.__class__) + if self._original_tag: + return cn[0] == self._original_tag + else: + return cn[0] == self + def set_attributes_from_previous (self, dict): self._dict.update (dict) @@ -615,6 +627,7 @@ class Part (Music_xml_node): attributes = copy.copy (attr) attributes._children = []; attributes._dict = attr._dict.copy () + attributes._original_tag = attr # copy only the relevant children over for the given staff for c in attr._children: if (not (hasattr (c, 'number') and (c.number != staff)) and diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index 83bcfa553a..a2e09e87e2 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -1559,6 +1559,7 @@ class LilyPondVoiceBuilder: self.measure_length = (4, 4) def _insert_multibar (self): + layout_information.set_context_item ('Score', 'skipBars = ##t') r = musicexp.MultiMeasureRest () lenfrac = Rational (self.measure_length[0], self.measure_length[1]) r.duration = rational_to_lily_duration (lenfrac) @@ -1792,25 +1793,6 @@ def musicxml_voice_to_lily_voice (voice): except NegativeSkip, neg: voice_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.Attributes): - if n.is_first () and n._measure_position == Rational (0): - try: - number = int (n.get_parent ().number) - except ValueError: - number = 0 - if number > 0: - voice_builder.add_bar_check (number) - figured_bass_builder.add_bar_check (number) - chordnames_builder.add_bar_check (number) - - for a in musicxml_attributes_to_lily (n): - voice_builder.add_command (a) - measure_length = measure_length_from_attributes (n, current_measure_length) - if current_measure_length != measure_length: - current_measure_length = measure_length - voice_builder.set_measure_length (current_measure_length) - continue if isinstance (n, musicxml.Barline): barlines = musicxml_barline_to_lily (n) @@ -1821,19 +1803,18 @@ def musicxml_voice_to_lily_voice (voice): voice_builder.add_command (a) continue - if not n.__class__.__name__ == 'Note': - n.message (_ ('unexpected %s; expected %s or %s or %s') % (n, 'Note', 'Attributes', 'Barline')) - continue - + # Continue any multimeasure-rests before trying to add bar checks! + # Don't handle new MM rests yet, because for them we want bar checks! rest = n.get_maybe_exist_typed_child (musicxml.Rest) - if (rest - and rest.is_whole_measure ()): - + if (rest and rest.is_whole_measure () + and voice_builder.pending_multibar > Rational (0)): voice_builder.add_multibar_rest (n._duration) continue - if n.is_first () and n._measure_position == Rational (0): - try: + + # print a bar check at the beginning of each measure! + if n.is_first () and n._measure_position == Rational (0) and n != voice._elements[0]: + try: num = int (n.get_parent ().number) except ValueError: num = 0 @@ -1842,6 +1823,24 @@ def musicxml_voice_to_lily_voice (voice): figured_bass_builder.add_bar_check (num) chordnames_builder.add_bar_check (num) + # Start any new multimeasure rests + if (rest and rest.is_whole_measure ()): + voice_builder.add_multibar_rest (n._duration) + continue + + if isinstance (n, musicxml.Attributes): + for a in musicxml_attributes_to_lily (n): + voice_builder.add_command (a) + measure_length = measure_length_from_attributes (n, current_measure_length) + if current_measure_length != measure_length: + current_measure_length = measure_length + voice_builder.set_measure_length (current_measure_length) + continue + + if not n.__class__.__name__ == 'Note': + n.message (_ ('unexpected %s; expected %s or %s or %s') % (n, 'Note', 'Attributes', 'Barline')) + continue + main_event = musicxml_note_to_lily_main_event (n) if main_event and not first_pitch: first_pitch = main_event.pitch -- 2.39.2