]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/musicexp.py
Merge branch 'master' of ssh://jomand@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / python / musicexp.py
index e87b996ea33921cea4dbb2eada635295ef87aa10..cab3c8d67f4303e70601e2ae920a020601ee0a19 100644 (file)
@@ -43,7 +43,6 @@ class Output_printer:
     Music expression as a .ly file.
     
     """
-    ## TODO: support for \relative.
     
     def __init__ (self):
         self._line = ''
@@ -205,10 +204,20 @@ class Duration:
 # Implement the different note names for the various languages
 def pitch_generic (pitch, notenames, accidentals):
     str = notenames[pitch.step]
-    if pitch.alteration < 0:
-        str += accidentals[0] * (-pitch.alteration)
+    halftones = int (pitch.alteration)
+    if halftones < 0:
+        str += accidentals[0] * (-halftones)
     elif pitch.alteration > 0:
-        str += accidentals[3] * (pitch.alteration)
+        str += accidentals[3] * (halftones)
+    # Handle remaining fraction to pitch.alteration (for microtones)
+    if (halftones != pitch.alteration):
+        if None in accidentals[1:3]:
+            warning (_ ("Language does not support microtones contained in the piece"))
+        else:
+            try:
+                str += {-0.5: accidentals[1], 0.5: accidentals[2]}[pitch.alteration-halftones]
+            except KeyError:
+                warning (_ ("Language does not support microtones contained in the piece"))
     return str
 
 def pitch_general (pitch):
@@ -230,7 +239,7 @@ def pitch_norsk (pitch):
     return pitch_deutsch (pitch)
 
 def pitch_svenska (pitch):
-    str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['ess', '', '', 'iss'])
+    str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['ess', None, None, 'iss'])
     return str.replace ('hess', 'b').replace ('aes', 'as').replace ('ees', 'es')
 
 def pitch_italiano (pitch):
@@ -241,11 +250,11 @@ def pitch_catalan (pitch):
     return pitch_italiano (pitch)
 
 def pitch_espanol (pitch):
-    str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', '', '', 's'])
+    str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 's'])
     return str
 
 def pitch_vlaams (pitch):
-    str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', '', '', 'k'])
+    str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 'k'])
     return str
 
 def set_pitch_language (language):
@@ -1297,9 +1306,9 @@ class TremoloEvent (ArticulationEvent):
 class BendEvent (ArticulationEvent):
     def __init__ (self):
         Event.__init__ (self)
-        self.alter = 0
+        self.alter = None
     def ly_expression (self):
-        if self.alter:
+        if self.alter != None:
             return "-\\bendAfter #%s" % self.alter
         else:
             return ''
@@ -1422,27 +1431,76 @@ class NoteEvent(RhythmicEvent):
 class KeySignatureChange (Music):
     def __init__ (self):
         Music.__init__ (self)
-        self.scale = []
-        self.tonic = Pitch()
+        self.tonic = None
         self.mode = 'major'
-        
+        self.non_standard_alterations = None
+
+    def format_non_standard_alteration (self, a):
+        alter_dict = { -2:   ",DOUBLE-FLAT",
+                       -1.5: ",THREE-Q-FLAT",
+                       -1:   ",FLAT",
+                       -0.5: ",SEMI-FLAT",
+                        0:   ",NATURAL",
+                        0.5: ",SEMI-SHARP",
+                        1:   ",SHARP",
+                        1.5: ",THREE-Q-SHARP",
+                        2:   ",DOUBLE-SHARP"}
+        try:
+            accidental = alter_dict[a[1]]
+        except KeyError:
+            warning (_ ("Unable to convert alteration %s to a lilypond expression") % a[1])
+            return ''
+        if len (a) == 2:
+            return "( %s . %s )" % (a[0], accidental)
+        elif len (a) == 3:
+            return "(( %s . %s ) . %s )" % (a[2], a[0], accidental)
+        else:
+            return ''
+
     def ly_expression (self):
-        return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
+        if self.tonic:
+            return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
                      self.mode)
-    
-    def lisp_expression (self):
-        pairs = ['(%d . %d)' % (i , self.scale[i]) for i in range (0,7)]
-        scale_str = ("'(%s)" % string.join (pairs))
-
-        return """ (make-music 'KeyChangeEvent
-     'pitch-alist %s) """ % scale_str
+        elif self.non_standard_alterations:
+            alterations = [self.format_non_standard_alteration (a) for
+                                        a in self.non_standard_alterations]
+            # TODO: Check if the alterations should really be given in reverse
+            #       order of if that's just a bug in Lilypond. If it's a bug,
+            #       fix it and remove the following call, otherwise add a
+            #       proper comment here!
+            alterations.reverse ()
+            return "\\set Staff.keySignature = #`(%s)" % string.join (alterations, " ")
+        else:
+            return ''
 
 class TimeSignatureChange (Music):
     def __init__ (self):
         Music.__init__ (self)
-        self.fraction = (4,4)
+        self.fractions = [4,4]
+        self.style = None
     def ly_expression (self):
-        return '\\time %d/%d ' % self.fraction
+        st = ''
+        # Print out the style if we have ome, but the '() should only be 
+        # forced for 2/2 or 4/4, since in all other cases we'll get numeric 
+        # signatures anyway despite the default 'C signature style!
+        is_common_signature = self.fractions in ([2,2], [4,4], [4,2])
+        if self.style:
+            if self.style == "common":
+                st = "\\defaultTimeSignature"
+            elif (self.style != "'()"):
+                st = "\\once \\override Staff.TimeSignature #'style = #%s " % self.style
+            if (self.style != "'()") or is_common_signature:
+                st = "\\numericTimeSignature"
+
+        # Easy case: self.fractions = [n,d] => normal \time n/d call:
+        if len (self.fractions) == 2 and isinstance (self.fractions[0], int):
+            return st + '\\time %d/%d ' % tuple (self.fractions)
+        elif self.fractions and not isinstance (self.fractions[0], list):
+            # TODO: Implement non-standard time-signatures
+            return st + ''
+        else:
+            # TODO: Implement non-standard time-signatures
+            return st + ''
     
 class ClefChange (Music):
     def __init__ (self):