from rational import Rational
+
class Output_stack_element:
def __init__ (self):
self.factor = Rational (1)
for e in self.elements:
e.set_start (start)
start += e.get_length()
-
-class EventChord(NestedMusic):
+
+class Lyrics:
+ def __init__ (self):
+ self.lyrics_syllables = []
+
+ def print_ly (self, printer):
+ printer.dump ("\lyricmode {")
+ for l in self.lyrics_syllables:
+ printer.dump ( "%s " % l )
+ printer.dump ("}")
+
+ def ly_expression (self):
+ lstr = "\lyricmode {\n "
+ for l in self.lyrics_syllables:
+ lstr += l + " "
+ lstr += "\n}"
+ return lstr
+
+
+class EventChord (NestedMusic):
def get_length (self):
l = Rational (0)
for e in self.elements:
class SpanEvent (Event):
def __init__(self):
Event.__init__ (self)
- self.span_direction = 0
+ self.span_direction = 0 # start/stop
+ self.line_type = 'solid'
+ self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
+ self.size = 0 # size of e.g. ocrave shift
+ def wait_for_note (self):
+ return True
def get_properties(self):
return "'span-direction %d" % self.span_direction
-
+ def set_span_type (self, type):
+ self.span_type = type
+
class SlurEvent (SpanEvent):
def ly_expression (self):
- return {-1: '(',
- 0:'',
- 1:')'}[self.span_direction]
+ before = ''
+ after = ''
+ # TODO: setting dashed/dotted line style does not work, because that
+ # command needs to be written before the note, not when the
+ # event is observed after the note!
+ #before = {'dotted': '\\slurDotted',
+ # 'dashed' : '\\slurDashed'}.get (self.line_type, '')
+ #if before:
+ #after = '\\slurSolid'
+
+ return {-1: before + '(' + after,
+ 1:')'}.get (self.span_direction, '')
class BeamEvent (SpanEvent):
def ly_expression (self):
return {-1: '[',
- 0:'',
- 1:']'}[self.span_direction]
+ 1:']'}.get (self.span_direction, '')
+
+class PedalEvent (SpanEvent):
+ def ly_expression (self):
+ return {-1: '\\sustainDown',
+ 1:'\\sustainUp'}.get (self.span_direction, '')
+
+# type==-1 means octave up, type==-2 means octave down
+class OctaveShiftEvent (SpanEvent):
+ def wait_for_note (self):
+ return False;
+ def set_span_type (self, type):
+ 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)
+ # negative values go up!
+ value *= -1*self.span_type
+ return value
+ def ly_expression (self):
+ dir = self.ly_octave_shift_indicator ()
+ value = ''
+ if dir:
+ value = '#(set-octavation %s)' % dir
+ return {
+ -1: value,
+ 1: '#(set-octavation 0)'}.get (self.span_direction, '')
+
+class TrillSpanEvent (SpanEvent):
+ def ly_expression (self):
+ return {-1: '\\startTrillSpan',
+ 0: '', # no need to write out anything for type='continue'
+ 1:'\\stopTrillSpan'}.get (self.span_direction, '')
+
+class GlissandoEvent (SpanEvent):
+ def ly_expression (self):
+ style = ''
+ # TODO: wavy-line glissandos don't work, becasue the style has to be
+ # set before the note, at the \glissando it's already too late!
+ #if self.line_type == 'wavy':
+ #style = "\once\override Glissando #'style = #'zigzag"
+ # In lilypond, glissando is NOT a spanner, unlike MusicXML.
+ return {-1: style + '\\glissando',
+ 1:''}.get (self.span_direction, '')
class ArpeggioEvent(Event):
+ def wait_for_note (self):
+ return True;
def ly_expression (self):
return ('\\arpeggio')
return '~'
-class HairpinEvent (Event):
- def __init__ (self, type):
- self.type = type
+class HairpinEvent (SpanEvent):
+ def set_span_type (self, type):
+ self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
def hairpin_to_ly (self):
- val = ''
- tp = { 0: '\!', 1: '\<', -1: '\>' }.get (self.type)
- if tp:
- val += tp
- return val
+ if self.span_direction == 1:
+ return '\!'
+ else:
+ return {1: '\<', -1: '\>'}.get (self.span_type, '')
def ly_expression (self):
return self.hairpin_to_ly ()
"mp", "mf",
"f", "ff", "fff", "ffff",
"fp", "sf", "sff", "sp", "spp", "sfz", "rfz" ];
+ def wait_for_note (self):
+ return True;
def ly_expression (self):
if self.type == None:
return;
elif self.type in self.available_commands:
return '\%s' % self.type
else:
- return '\markup{ \dynamic %s }' % self.type
+ return '-\markup{ \dynamic %s }' % self.type
def print_ly (self, printer):
if self.type == None:
elif self.type in self.available_commands:
printer.dump ("\\%s" % self.type)
else:
- printer.dump ("\\markup{ \\dynamic %s }" % self.type)
+ printer.dump ("-\\markup{ \\dynamic %s }" % self.type)
class ArticulationEvent (Event):
self.force_direction = None
def direction_mod (self):
- dirstr = { 1: '^', -1: '_', 0: '-' }.get (self.force_direction)
- if dirstr:
- return dirstr
- else:
- return ''
+ return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '')
def ly_expression (self):
return '%s\\%s' % (self.direction_mod (), self.type)
+class ShortArticulationEvent (ArticulationEvent):
+ def direction_mod (self):
+ # default is -
+ return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
+ def ly_expression (self):
+ return '%s%s' % (self.direction_mod (), self.type)
class TremoloEvent (Event):
def __init__ (self):
- self.bars = 0;
+ Event.__init__ (self)
+ self.bars = 0
def ly_expression (self):
str=''
str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
return str
+class BendEvent (Event):
+ def __init__ (self):
+ Event.__init__ (self)
+ self.alter = 0
+ def ly_expression (self):
+ if self.alter:
+ return "-\\bendAfter #%s" % self.alter
+ else:
+ return ''
class RhythmicEvent(Event):
def __init__ (self):
self.forced_accidental = False
def get_properties (self):
- str = RhythmicEvent.get_properties ()
+ str = RhythmicEvent.get_properties (self)
if self.pitch:
str += self.pitch.lisp_expression ()
def __init__ (self):
Music.__init__ (self)
self.type = 'G'
-
-
+ self.position = 2
+ self.octave = 0
+
+ def octave_modifier (self):
+ return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
+ def clef_name (self):
+ return {('G', 2): "treble",
+ ('G', 1): "french",
+ ('C', 1): "soprano",
+ ('C', 2): "mezzosoprano",
+ ('C', 3): "alto",
+ ('C', 4): "tenor",
+ ('C', 5): "baritone",
+ ('F', 3): "varbaritone",
+ ('F', 4): "bass",
+ ('F', 5): "subbass",
+ ("percussion", 2): "percussion",
+ ("TAB", 5): "tab"}.get ((self.type, self.position), None)
def ly_expression (self):
- return '\\clef "%s"' % self.type
+ return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
+
clef_dict = {
"G": ("clefs.G", -2, -6),
"C": ("clefs.C", 0, 0),
}
def lisp_expression (self):
- (glyph, pos, c0) = self.clef_dict [self.type]
+ try:
+ (glyph, pos, c0) = self.clef_dict[self.type]
+ except KeyError:
+ return ""
clefsetting = """
(make-music 'SequentialMusic
'elements (list