]> git.donarmstrong.com Git - lilypond.git/commitdiff
MusicXML: Implement <degree> to modify chords (add/remove/alter); support bass
authorReinhold Kainhofer <reinhold@kainhofer.com>
Fri, 11 Apr 2008 18:56:56 +0000 (20:56 +0200)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Sat, 12 Apr 2008 20:15:14 +0000 (22:15 +0200)
Signed-off-by: Reinhold Kainhofer <reinhold@kainhofer.com>
python/musicexp.py
python/musicxml.py
scripts/musicxml2ly.py

index 5efff8a4162caef574f2a4f388de8c10798a9a5a..8cedf06decc53021dc3f499505e833b241af065f 100644 (file)
@@ -1099,7 +1099,7 @@ class FretEvent (MarkupEvent):
         else:
             return ''
 
-class ChordRoot:
+class ChordPitch:
     def __init__ (self):
         self.alteration = 0
         self.step = 0
@@ -1108,12 +1108,30 @@ class ChordRoot:
     def ly_expression (self): 
         return pitch_generating_function (self)
 
+class ChordModification:
+    def __init__ (self):
+        self.alteration = 0
+        self.step = 0
+        self.type = 0
+    def ly_expression (self):
+        if self.type:
+            val = {1: ".", -1: "^" }.get (self.type, "")
+            val += "%s" % self.step
+            val += {1: "+", -1: "-"}.get (self.alteration, "")
+            return val
+        else:
+            return ''
+
 class ChordNameEvent (Event):
     def __init__ (self):
         Event.__init__ (self)
         self.root = None
         self.kind = None
         self.duration = None
+        self.modifications = []
+        self.bass = None
+    def add_modification (self, mod):
+        self.modifications.append (mod)
     def ly_expression (self):
         if not self.root:
             return ''
@@ -1123,6 +1141,15 @@ class ChordNameEvent (Event):
         if self.kind:
             value += ":"
             value += self.kind
+        # First print all additions/changes, and only afterwards all subtractions
+        for m in self.modifications:
+            if m.type == 1:
+              value += m.ly_expression ()
+        for m in self.modifications:
+            if m.type == -1:
+              value += m.ly_expression ()
+        if self.bass:
+            value += "/%s" % self.bass.ly_expression ()
         return value
 
 
index c71bf2d0be68ba9cecd8fe9ca88900a32b19187b..5afd4f27952e6b3d6701c2e3700991b2b7a7fd29 100644 (file)
@@ -872,17 +872,48 @@ class Words (Music_xml_node):
 class Harmony (Music_xml_node):
     pass
 
-class Root (Music_xml_node):
+class ChordPitch (Music_xml_node):
+    def step_class_name (self):
+        return u'root-step'
+    def alter_class_name (self):
+        return u'root-alter'
     def get_step (self):
-        ch = self.get_unique_typed_child (get_class (u'root-step'))
+        ch = self.get_unique_typed_child (get_class (self.step_class_name ()))
         return ch.get_text ().strip ()
     def get_alteration (self):
-        ch = self.get_maybe_exist_typed_child (get_class (u'root-alter'))
+        ch = self.get_maybe_exist_typed_child (get_class (self.alter_class_name ()))
         alter = 0
         if ch:
             alter = int (ch.get_text ().strip ())
         return alter
 
+class Root (ChordPitch):
+    pass
+
+class Bass (ChordPitch):
+    def step_class_name (self):
+        return u'bass-step'
+    def alter_class_name (self):
+        return u'bass-alter'
+
+class ChordModification (Music_xml_node):
+    def get_type (self):
+        ch = self.get_maybe_exist_typed_child (get_class (u'degree-type'))
+        return {'add': 1, 'alter': 1, 'subtract': -1}.get (ch.get_text ().strip (), 0)
+    def get_value (self):
+        ch = self.get_maybe_exist_typed_child (get_class (u'degree-value'))
+        value = 0
+        if ch:
+            value = int (ch.get_text ().strip ())
+        return value
+    def get_alter (self):
+        ch = self.get_maybe_exist_typed_child (get_class (u'degree-alter'))
+        value = 0
+        if ch:
+            value = int (ch.get_text ().strip ())
+        return value
+
+
 class Frame (Music_xml_node):
     def get_frets (self):
         return self.get_named_child_value_number ('frame-frets', 4)
@@ -929,6 +960,7 @@ class_dict = {
        'attributes': Attributes,
         'barline': Barline,
         'bar-style': BarStyle,
+        'bass': Bass,
        'beam' : Beam,
         'beat-unit': BeatUnit,
         'beat-unit-dot': BeatUnitDot,
@@ -936,6 +968,7 @@ class_dict = {
         'bracket' : Bracket,
        'chord': Chord,
         'dashes' : Dashes,
+        'degree' : ChordModification,
        'dot': Dot,
        'direction': Direction,
         'direction-type': DirType,
index 3bed2ed9be0833385b0280bf5afd84fa8523d37b..22f78523754131cca185450ff076ce901ae72d35 100644 (file)
@@ -1311,14 +1311,14 @@ def musicxml_harmony_to_lily (n):
     return res
 
 
-def musicxml_chordroot_to_lily (mxl_root):
-    r = musicexp.ChordRoot ()
-    r.alteration = mxl_root.get_alteration ()
-    r.step = musicxml_step_to_lily (mxl_root.get_step ())
+def musicxml_chordpitch_to_lily (mxl_cpitch):
+    r = musicexp.ChordPitch ()
+    r.alteration = mxl_cpitch.get_alteration ()
+    r.step = musicxml_step_to_lily (mxl_cpitch.get_step ())
     return r
 
 chordkind_dict = {
-    'major': '',
+    'major': '5',
     'minor': 'm',
     'augmented': 'aug',
     'diminished': 'dim',
@@ -1357,7 +1357,7 @@ chordkind_dict = {
     #'pedal': '???',(pedal-point bass)
     #'power': '???',(perfect fifth)
     #'Tristan': '???',
-    #'other': '',
+    'other': '1',
     'none': None,
 }
 
@@ -1373,20 +1373,31 @@ def musicxml_harmony_to_lily_chordname (n):
     root = n.get_maybe_exist_named_child ('root')
     if root:
         ev = musicexp.ChordNameEvent ()
-        ev.root = musicxml_chordroot_to_lily (root)
+        ev.root = musicxml_chordpitch_to_lily (root)
         kind = n.get_maybe_exist_named_child ('kind')
         if kind:
             ev.kind = musicxml_chordkind_to_lily (kind.get_text ())
+            if not ev.kind:
+                return res
+        bass = n.get_maybe_exist_named_child ('bass')
+        if bass:
+            ev.bass = musicxml_chordpitch_to_lily (bass)
+        inversion = n.get_maybe_exist_named_child ('inversion')
+        if inversion:
+            # TODO: Lilypond does not support inversions, does it?
+            pass
+        for deg in n.get_named_children ('degree'):
+            d = musicexp.ChordModification ()
+            d.type = deg.get_type ()
+            d.step = deg.get_value ()
+            d.alteration = deg.get_alter ()
+            ev.add_modification (d)
         #TODO: convert the user-symbols attribute: 
             #major: a triangle, like Unicode 25B3
             #minor: -, like Unicode 002D
             #augmented: +, like Unicode 002B
             #diminished: (degree), like Unicode 00B0
             #half-diminished: (o with slash), like Unicode 00F8
-        # TODO: Convert the inversion and bass children
-        for deg in n.get_named_children ('degree'):
-            # TODO: Convert the added/removed degrees to lilypond
-            pass
         if ev and ev.root:
             res.append (ev)