]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/musicexp.py
MusicXML: Implement metronome mark (tempo marks)
[lilypond.git] / python / musicexp.py
index adce6911013d207cbb5042f068d3ab975ad9b0a5..0346e91f4c96df400292d751f6a3641d96af63f4 100644 (file)
@@ -2,9 +2,9 @@ import inspect
 import sys
 import string
 import re
-import lilylib
+import lilylib as ly
 
-_ = lilylib._
+_ = ly._
 
 from rational import Rational
 
@@ -152,11 +152,19 @@ class Duration:
                              self.factor.denominator ())
 
 
-    def ly_expression (self, factor = None):
+    def ly_expression (self, factor = None, scheme_mode = False):
         if not factor:
             factor = self.factor
-            
-        str = '%d%s' % (1 << self.duration_log, '.'*self.dots)
+
+        if self.duration_log < 0:
+            if scheme_mode:
+                longer_dict = {-1: "breve", -2: "longa"}
+            else:
+                longer_dict = {-1: "\\breve", -2: "\\longa"}
+            str = longer_dict.get (self.duration_log, "1")
+        else:
+            str = '%d' % (1 << self.duration_log)
+        str += '.'*self.dots
 
         if factor <> Rational (1,1):
             if factor.denominator () <> 1:
@@ -855,9 +863,17 @@ class TextSpannerEvent (SpanEvent):
             1:'\\stopTextSpan'}.get (self.span_direction, '')
 
 class BracketSpannerEvent (SpanEvent):
+    # Ligature brackets use prefix-notation!!!
+    def print_before_note (self, printer):
+        if self.span_direction == -1:
+            printer.dump ('\[')
+    # the the bracket after the last note
+    def print_after_note (self, printer):
+        if self.span_direction == 1:
+            printer.dump ('\]')
+    # we're printing everything in print_(before|after)_note...
     def ly_expression (self):
-        return {-1: '\\startGroup',
-            1:'\\stopGroup'}.get (self.span_direction, '')
+        return '';
 
 
 class OctaveShiftEvent (SpanEvent):
@@ -1259,6 +1275,108 @@ class StaffChange (Music):
             return ''
 
 
+class TempoMark (Music):
+    def __init__ (self):
+        Music.__init__ (self)
+        self.baseduration = None
+        self.newduration = None
+        self.beats = None
+        self.parentheses = False
+    def set_base_duration (self, dur):
+        self.baseduration = dur
+    def set_new_duration (self, dur):
+        self.newduration = dur
+    def set_beats_per_minute (self, beats):
+        self.beats = beats
+    def set_parentheses (self, parentheses):
+        self.parentheses = parentheses
+    def wait_for_note (self):
+        return False
+    def duration_to_markup (self, dur):
+        if dur:
+            # Generate the markup to print the note, use scheme mode for 
+            # ly_expression to get longa and not \longa (which causes an error)
+            return "\\general-align #Y #DOWN \\smaller \\note #\"%s\" #UP" % dur.ly_expression(None, True)
+        else:
+            return ''
+    def tempo_markup_template (self):
+        return "\\mark\\markup { \\fontsize #-2 \\line { %s } }"
+    def ly_expression (self):
+        res = ''
+        if not self.baseduration:
+            return res
+        if self.beats:
+            if self.parentheses:
+                dm = self.duration_to_markup (self.baseduration)
+                contents = "\"(\" %s = %s \")\"" % (dm, self.beats)
+                res += self.tempo_markup_template() % contents
+            else:
+                res += "\\tempo %s=%s" % (self.baseduration.ly_expression(), self.beats)
+        elif self.newduration:
+            dm = self.duration_to_markup (self.baseduration)
+            ndm = self.duration_to_markup (self.newduration)
+            if self.parentheses:
+                contents = "\"(\" %s = %s \")\"" % (dm, ndm)
+            else:
+                contents = " %s = %s " % (dm, ndm)
+            res += self.tempo_markup_template() % contents
+        else:
+            return ''
+        return res
+
+class FiguredBassNote (Music):
+    def __init__ (self):
+        Music.__init__ (self)
+        self.number = ''
+        self.prefix = ''
+        self.suffix = ''
+    def set_prefix (self, prefix):
+        self.prefix = prefix
+    def set_suffix (self, suffix):
+        self.prefix = suffix
+    def set_number (self, number):
+        self.number = number
+    def ly_expression (self):
+        res = ''
+        if self.number:
+            res += self.number
+        else:
+            res += '_'
+        if self.prefix:
+            res += self.prefix
+        if self.suffix:
+            res += self.suffix
+        return res
+
+
+class FiguredBassEvent (NestedMusic):
+    def __init__ (self):
+        NestedMusic.__init__ (self)
+        self.duration = None
+        self.real_duration = 0
+        self.parentheses = False
+        return
+    def set_duration (self, dur):
+        self.duration = dur
+    def set_parentheses (self, par):
+        self.parentheses = par
+    def set_real_duration (self, dur):
+        self.real_duration = dur
+
+    def print_ly (self, printer):
+        figured_bass_events = [e for e in self.elements if
+               isinstance (e, FiguredBassNote)]
+        if figured_bass_events:
+          notes = []
+          for x in figured_bass_events:
+              notes.append (x.ly_expression ())
+          contents = string.join (notes)
+          if self.parentheses:
+              contents = '[%s]' % contents
+          printer ('<%s>' % contents)
+          self.duration.print_ly (printer)
+
+
 class MultiMeasureRest(Music):
 
     def lisp_expression (self):
@@ -1376,7 +1494,7 @@ class Staff (StaffGroup):
             printer.newline ()
             n = 0
             nr_voices = len (voices)
-            for [v, lyrics] in voices:
+            for [v, lyrics, figuredbass] in voices:
                 n += 1
                 voice_count_text = ''
                 if nr_voices > 1:
@@ -1388,6 +1506,8 @@ class Staff (StaffGroup):
                 for l in lyrics:
                     printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
                     printer.newline()
+                if figuredbass:
+                    printer ('\context FiguredBass = "%s" \\%s' % (figuredbass, figuredbass))
             printer ('>>')
 
     def print_ly (self, printer):