X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=python%2Fmusicexp.py;h=6bf587be8ff213d184ecac9ca075c87511652de2;hb=f69bd6761b3b3c077b0b994bd65b5a5bd79b5582;hp=a2d405973bcea05008e0da791c638021b1ae9f45;hpb=35cc20ad3b54a73a183f4453ab2df7dd85320f55;p=lilypond.git diff --git a/python/musicexp.py b/python/musicexp.py index a2d405973b..6bf587be8f 100644 --- a/python/musicexp.py +++ b/python/musicexp.py @@ -43,7 +43,6 @@ class Output_printer: Music expression as a .ly file. """ - ## TODO: support for \relative. def __init__ (self): self._line = '' @@ -205,11 +204,20 @@ class Duration: # Implement the different note names for the various languages def pitch_generic (pitch, notenames, accidentals): str = notenames[pitch.step] - # TODO: Handle microtones! - 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): @@ -231,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): @@ -242,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): @@ -884,10 +892,10 @@ class BarLine (Music): self.type = None def print_ly (self, printer): - bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': ":", + bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': "dashed", 'heavy': "|", 'light-light': "||", 'light-heavy': "|.", 'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'", - 'short': "'", 'none': "" }.get (self.type, None) + 'short': "'|", 'none': "" }.get (self.type, None) if bar_symbol <> None: printer.dump ('\\bar "%s"' % bar_symbol) else: @@ -983,7 +991,11 @@ class OctaveShiftEvent (SpanEvent): self.span_type = {'up': 1, 'down': -1}.get (type, 0) def ly_octave_shift_indicator (self): # convert 8/15 to lilypond indicators (+-1/+-2) - value = {8: 1, 15: 2}.get (self.size, 0) + try: + value = {8: 1, 15: 2}[self.size] + except KeyError: + warning (_ ("Invalid octave shift size found: %s. Using no shift.") % self.size) + value = 0 # negative values go up! value *= -1*self.span_type return value @@ -1298,9 +1310,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 '' @@ -1428,15 +1440,24 @@ class KeySignatureChange (Music): self.non_standard_alterations = None def format_non_standard_alteration (self, a): - alter_dict = { -2: ",DOUBLE-FLAT", - -1: ",FLAT", - 0: ",NATURAL", - 1: ",SHARP", - 2: ",DOUBLE-SHARP"} + 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], alter_dict.get (a[1], a[1])) + return "( %s . %s )" % (a[0], accidental) elif len (a) == 3: - return "(( %s . %s ) . %s )" % (a[2], a[0], alter_dict.get (a[1], a[1])) + return "(( %s . %s ) . %s )" % (a[2], a[0], accidental) else: return '' @@ -1452,7 +1473,6 @@ class KeySignatureChange (Music): # fix it and remove the following call, otherwise add a # proper comment here! alterations.reverse () - print "Non-Standard alterations printed out: %s" % alterations return "\\set Staff.keySignature = #`(%s)" % string.join (alterations, " ") else: return '' @@ -1462,6 +1482,13 @@ class TimeSignatureChange (Music): Music.__init__ (self) self.fractions = [4,4] self.style = None + def format_fraction (self, frac): + if isinstance (frac, list): + l = [self.format_fraction (f) for f in frac] + return "(" + string.join (l, " ") + ")" + else: + return "%s" % frac + def ly_expression (self): st = '' # Print out the style if we have ome, but the '() should only be @@ -1469,17 +1496,19 @@ class TimeSignatureChange (Music): # 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 != "'()") or is_common_signature: + if self.style == "common": + st = "\\defaultTimeSignature" + elif (self.style != "'()"): st = "\\once \\override Staff.TimeSignature #'style = #%s " % self.style + elif (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 + '' + elif self.fractions: + return st + "\\compoundMeter #'%s" % self.format_fraction (self.fractions) else: - # TODO: Implement non-standard time-signatures return st + '' class ClefChange (Music): @@ -1503,6 +1532,8 @@ class ClefChange (Music): ('F', 4): "bass", ('F', 5): "subbass", ("percussion", 2): "percussion", + # Workaround: MuseScore uses PERC instead of percussion + ("PERC", 2): "percussion", ("TAB", 5): "tab"}.get ((self.type, self.position), None) def ly_expression (self): return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())