Music expression as a .ly file.
"""
- ## TODO: support for \relative.
def __init__ (self):
self._line = ''
self.factor.denominator ())
- def ly_expression (self, factor = None):
+ def ly_expression (self, factor = None, scheme_mode = False):
if not factor:
factor = self.factor
if self.duration_log < 0:
- str = {-1: "\\breve", -2: "\\longa"}.get (self.duration_log, "1")
+ 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
# 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):
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):
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):
self.alteration = 0
self.step = 0
self.octave = 0
+ self._force_absolute_pitch = False
def __repr__(self):
return self.ly_expression()
def ly_expression (self):
str = self.ly_step_expression ()
- if relative_pitches:
+ if relative_pitches and not self._force_absolute_pitch:
str += self.relative_pitch ()
else:
str += self.absolute_pitch ()
relative_pitches = prev_relative_pitches
class TimeScaledMusic (MusicWrapper):
+ def __init__ (self):
+ MusicWrapper.__init__ (self)
+ self.numerator = 1
+ self.denominator = 1
+ self.display_number = "actual" # valid values "actual" | "both" | None
+ # Display the basic note length for the tuplet:
+ self.display_type = None # value values "actual" | "both" | None
+ self.display_bracket = "bracket" # valid values "bracket" | "curved" | None
+ self.actual_type = None # The actually played unit of the scaling
+ self.normal_type = None # The basic unit of the scaling
+ self.display_numerator = None
+ self.display_denominator = None
+
def print_ly (self, func):
+ if self.display_bracket == None:
+ func ("\\once \\override TupletBracket #'stencil = ##f")
+ func.newline ()
+ elif self.display_bracket == "curved":
+ warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
+ func ("\\once \\override TupletBracket #'stencil = #ly:slur::print")
+ func.newline ()
+
+ base_number_function = {None: "#f",
+ "actual": "tuplet-number::calc-denominator-text",
+ "both": "tuplet-number::calc-fraction-text"}.get (self.display_number, None)
+ # If we have non-standard numerator/denominator, use our custom function
+ if self.display_number == "actual" and self.display_denominator:
+ base_number_function = "(tuplet-number::non-default-tuplet-denominator-text %s)" % self.display_denominator
+ elif self.display_number == "both" and (self.display_denominator or self.display_numerator):
+ if self.display_numerator:
+ num = self.display_numerator
+ else:
+ num = "#f"
+ if self.display_denominator:
+ den = self.display_denominator
+ else:
+ den = "#f"
+ base_number_function = "(tuplet-number::non-default-tuplet-fraction-text %s %s)" % (den, num)
+
+
+ if self.display_type == "actual" and self.normal_type:
+ # Obtain the note duration in scheme-mode, i.e. \longa as \\longa
+ base_duration = self.normal_type.ly_expression (None, True)
+ func ("\\once \\override TupletNumber #'text = #(tuplet-number::append-note-wrapper %s \"%s\")" %
+ (base_number_function, base_duration))
+ func.newline ()
+ elif self.display_type == "both": # TODO: Implement this using actual_type and normal_type!
+ if self.display_number == None:
+ func ("\\once \\override TupletNumber #'stencil = ##f")
+ func.newline ()
+ elif self.display_number == "both":
+ den_duration = self.normal_type.ly_expression (None, True)
+ # If we don't have an actual type set, use the normal duration!
+ if self.actual_type:
+ num_duration = self.actual_type.ly_expression (None, True)
+ else:
+ num_duration = den_duration
+ if (self.display_denominator or self.display_numerator):
+ func ("\\once \\override TupletNumber #'text = #(tuplet-number::non-default-fraction-with-notes %s \"%s\" %s \"%s\")" %
+ (self.display_denominator, den_duration,
+ self.display_numerator, num_duration))
+ func.newline ()
+ else:
+ func ("\\once \\override TupletNumber #'text = #(tuplet-number::fraction-with-notes \"%s\" \"%s\")" %
+ (den_duration, num_duration))
+ func.newline ()
+ else:
+ if self.display_number == None:
+ func ("\\once \\override TupletNumber #'stencil = ##f")
+ func.newline ()
+ elif self.display_number == "both":
+ func ("\\once \\override TupletNumber #'text = #%s" % base_number_function)
+ func.newline ()
+
func ('\\times %d/%d ' %
(self.numerator, self.denominator))
func.add_factor (Rational (self.numerator, self.denominator))
self.music = SequentialMusic ()
self.music.elements = music
else:
- warning (_ ("unable to set the music %(music)s for the repeat %(repeat)s" % \
- {'music':music, 'repeat':self}))
+ warning (_ ("unable to set the music %(music)s for the repeat %(repeat)s") % \
+ {'music':music, 'repeat':self})
def add_ending (self, music):
self.endings.append (music)
def print_ly (self, printer):
class ChordEvent (NestedMusic):
def __init__ (self):
NestedMusic.__init__ (self)
+ self.after_grace_elements = None
self.grace_elements = None
self.grace_type = None
def append_grace (self, element):
if not self.grace_elements:
self.grace_elements = SequentialMusic ()
self.grace_elements.append (element)
+ def append_after_grace (self, element):
+ if element:
+ if not self.after_grace_elements:
+ self.after_grace_elements = SequentialMusic ()
+ self.after_grace_elements.append (element)
+
+ def has_elements (self):
+ return [e for e in self.elements if
+ isinstance (e, NoteEvent) or isinstance (e, RestEvent)] != []
+
def get_length (self):
l = Rational (0)
for e in self.elements:
l = max(l, e.get_length())
return l
-
+
+ def get_duration (self):
+ note_events = [e for e in self.elements if
+ isinstance (e, NoteEvent) or isinstance (e, RestEvent)]
+ if note_events:
+ return note_events[0].duration
+ else:
+ return None
+
def print_ly (self, printer):
note_events = [e for e in self.elements if
isinstance (e, NoteEvent)]
other_events = [e for e in self.elements if
not isinstance (e, RhythmicEvent)]
+ if self.after_grace_elements:
+ printer ('\\afterGrace {')
+
if self.grace_elements and self.elements:
if self.grace_type:
printer ('\\%s' % self.grace_type)
printer ('\\grace')
# don't print newlines after the { and } braces
self.grace_elements.print_ly (printer, False)
+ elif self.grace_elements: # no self.elements!
+ warning (_ ("Grace note with no following music: %s") % self.grace_elements)
+ if self.grace_type:
+ printer ('\\%s' % self.grace_type)
+ else:
+ printer ('\\grace')
+ self.grace_elements.print_ly (printer, False)
+ printer ('{}')
+
# Print all overrides and other settings needed by the
# articulations/ornaments before the note
for e in other_events:
pitches = []
basepitch = None
for x in note_events:
- pitches.append (x.pitch.ly_expression ())
+ pitches.append (x.chord_element_ly ())
if not basepitch:
basepitch = previous_pitch
printer ('<%s>' % string.join (pitches))
previous_pitch = basepitch
- note_events[0].duration.print_ly (printer)
+ duration = self.get_duration ()
+ if duration:
+ duration.print_ly (printer)
else:
pass
for e in other_events:
e.print_after_note (printer)
+ if self.after_grace_elements:
+ printer ('}')
+ self.after_grace_elements.print_ly (printer, False)
+
self.print_comment (printer)
class Partial (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:
if self.bar_number > 0 and (self.bar_number % 10) == 0:
printer.dump ("\\barNumberCheck #%d " % self.bar_number)
- else:
+ elif self.bar_number > 0:
printer.print_verbatim (' %% %d' % self.bar_number)
printer.newline ()
class PedalEvent (SpanEvent):
def ly_expression (self):
- return {-1: '\\sustainDown',
- 0:'\\sustainUp\\sustainDown',
- 1:'\\sustainUp'}.get (self.span_direction, '')
+ return {-1: '\\sustainOn',
+ 0:'\\sustainOff\\sustainOn',
+ 1:'\\sustainOff'}.get (self.span_direction, '')
class TextSpannerEvent (SpanEvent):
def ly_expression (self):
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
dir = self.ly_octave_shift_indicator ()
value = ''
if dir:
- value = '#(set-octavation %s)' % dir
+ value = '\ottava #%s' % dir
return {
-1: value,
- 1: '#(set-octavation 0)'}.get (self.span_direction, '')
+ 1: '\ottava #0'}.get (self.span_direction, '')
class TrillSpanEvent (SpanEvent):
def ly_expression (self):
if self.non_arpeggiate:
printer.dump ("\\arpeggioBracket")
else:
- dir = { -1: "\\arpeggioDown", 1: "\\arpeggioUp" }.get (self.direction, '')
+ dir = { -1: "\\arpeggioArrowDown", 1: "\\arpeggioArrowUp" }.get (self.direction, '')
if dir:
printer.dump (dir)
def print_after_note (self, printer):
if self.non_arpeggiate or self.direction:
- printer.dump ("\\arpeggioNeutral")
+ printer.dump ("\\arpeggioNormal")
def ly_expression (self):
return ('\\arpeggio')
else:
return ''
+
+class FunctionWrapperEvent (Event):
+ def __init__ (self, function_name = None):
+ Event.__init__ (self)
+ self.function_name = function_name
+ def pre_note_ly (self, is_chord_element):
+ if self.function_name:
+ return "\\%s" % self.function_name
+ else:
+ return ''
+ def pre_chord_ly (self):
+ return ''
+ def ly_expression (self):
+ if self.function_name:
+ return "\\%s" % self.function_name
+ else:
+ return ''
+
+class ParenthesizeEvent (FunctionWrapperEvent):
+ def __init__ (self):
+ FunctionWrapperEvent.__init__ (self, "parenthesize")
+
+class NotestyleEvent (Event):
+ def __init__ (self):
+ Event.__init__ (self)
+ self.style = None
+ self.filled = None
+ def pre_chord_ly (self):
+ if self.style:
+ return "\\once \\override NoteHead #'style = #%s" % self.style
+ else:
+ return ''
+ def pre_note_ly (self, is_chord_element):
+ if self.style and is_chord_element:
+ return "\\tweak #'style #%s" % self.style
+ else:
+ return ''
+ def ly_expression (self):
+ return self.pre_chord_ly ()
+
+
+class ChordPitch:
+ def __init__ (self):
+ self.alteration = 0
+ self.step = 0
+ def __repr__(self):
+ return self.ly_expression()
+ 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 ''
+ value = self.root.ly_expression ()
+ if self.duration:
+ value += self.duration.ly_expression ()
+ 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
+
+
class TremoloEvent (ArticulationEvent):
def __init__ (self):
Event.__init__ (self)
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 ''
def __init__ (self):
Event.__init__ (self)
self.duration = Duration()
-
+ self.associated_events = []
+
+ def add_associated_event (self, ev):
+ if ev:
+ self.associated_events.append (ev)
+
+ def pre_chord_ly (self):
+ return [ev.pre_chord_ly () for ev in self.associated_events]
+
+ def pre_note_ly (self, is_chord_element):
+ return [ev.pre_note_ly (is_chord_element) for ev in self.associated_events]
+
+ def ly_expression_pre_note (self, is_chord_element):
+ res = string.join (self.pre_note_ly (is_chord_element), ' ')
+ if res != '':
+ res = res + ' '
+ return res
+
def get_length (self):
return self.duration.get_length()
def __init__ (self):
RhythmicEvent.__init__ (self)
self.pitch = None
+
def ly_expression (self):
+ res = self.ly_expression_pre_note (False)
if self.pitch:
- return "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
+ return res + "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
else:
return 'r%s' % self.duration.ly_expression ()
def print_ly (self, printer):
+ for ev in self.associated_events:
+ ev.print_ly (printer)
if self.pitch:
self.pitch.print_ly (printer)
self.duration.print_ly (printer)
self.drum_type = None
self.cautionary = False
self.forced_accidental = False
-
+
def get_properties (self):
str = RhythmicEvent.get_properties (self)
excl_question += '!'
return excl_question
-
+
def ly_expression (self):
+ # obtain all stuff that needs to be printed before the note:
+ res = self.ly_expression_pre_note (True)
if self.pitch:
- return '%s%s%s' % (self.pitch.ly_expression (),
+ return res + '%s%s%s' % (self.pitch.ly_expression (),
self.pitch_mods(),
self.duration.ly_expression ())
elif self.drum_type:
- return '%s%s' (self.drum_type,
+ return res + '%s%s' (self.drum_type,
self.duration.ly_expression ())
+ def chord_element_ly (self):
+ # obtain all stuff that needs to be printed before the note:
+ res = self.ly_expression_pre_note (True)
+ if self.pitch:
+ return res + '%s%s' % (self.pitch.ly_expression (),
+ self.pitch_mods())
+ elif self.drum_type:
+ return res + '%s%s' (self.drum_type)
+
+
def print_ly (self, printer):
+ for ev in self.associated_events:
+ ev.print_ly (printer)
if self.pitch:
self.pitch.print_ly (printer)
printer (self.pitch_mods ())
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]
+ 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 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):
- 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
+ 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:
+ return st + "\\compoundMeter #'%s" % self.format_fraction (self.fractions)
+ else:
+ return st + ''
class ClefChange (Music):
def __init__ (self):
""" % (glyph, pos, c0)
return clefsetting
+class Transposition (Music):
+ def __init__ (self):
+ Music.__init__ (self)
+ self.pitch = None
+ def ly_expression (self):
+ self.pitch._force_absolute_pitch = True
+ return '\\transposition %s' % self.pitch.ly_expression ()
class StaffChange (Music):
def __init__ (self, staff):
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:
+ res += "\\tempo \"\" %s=%s" % (self.baseduration.ly_expression(), self.beats)
+ 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):
return 'R%s' % self.duration.ly_expression ()
+class Break (Music):
+ def __init__ (self, tp="break"):
+ Music.__init__ (self)
+ self.type = tp
+ def print_ly (self, printer):
+ if self.type:
+ printer.dump ("\\%s" % self.type)
+
class StaffGroup:
def __init__ (self, command = "StaffGroup"):
self.stafftype = command
sub_staff_type = self.stafftype
for [staff_id, voices] in self.part_information:
+ # Chord names need to come before the staff itself!
+ for [v, lyrics, figuredbass, chordnames] in voices:
+ if chordnames:
+ printer ('\context ChordNames = "%s" \\%s' % (chordnames, chordnames))
+
+ # now comes the real staff definition:
if staff_id:
printer ('\\context %s = "%s" << ' % (sub_staff_type, staff_id))
else:
printer.newline ()
n = 0
nr_voices = len (voices)
- for [v, lyrics] in voices:
+ for [v, lyrics, figuredbass, chordnames] in voices:
n += 1
voice_count_text = ''
if nr_voices > 1:
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):
class RhythmicStaff (Staff):
def __init__ (self, command = "RhythmicStaff"):
Staff.__init__ (self, command)
+
+class Score:
+ def __init__ (self):
+ self.contents = None
+ self.create_midi = False
+
+ def set_contents (self, contents):
+ self.contents = contents
+
+ def set_part_information (self, part_id, staves_info):
+ if self.contents:
+ self.contents.set_part_information (part_id, staves_info)
+
+ def print_ly (self, printer):
+ printer.dump ("\\score {");
+ printer.newline ()
+ if self.contents:
+ self.contents.print_ly (printer);
+ printer.dump ("\\layout {}");
+ printer.newline ()
+ if not self.create_midi:
+ printer.dump ("% To create MIDI output, uncomment the following line:");
+ printer.newline ();
+ printer.dump ("% ");
+ printer.dump ("\\midi {}");
+ printer.newline ()
+ printer.dump ("}");
+ printer.newline ()
def test_pitch ():