X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=python%2Fmusicexp.py;h=01cd446f481fc0b83c33fed9e5783aea3d78c00f;hb=d4863ea22d370923fb7558cc300f9c058760a817;hp=2ae8a6784f3ea480f3343d6539323fd79ec706d0;hpb=84dfa31321b6f0c3224ed8c586b64ec97e88402f;p=lilypond.git diff --git a/python/musicexp.py b/python/musicexp.py index 2ae8a6784f..01cd446f48 100644 --- a/python/musicexp.py +++ b/python/musicexp.py @@ -152,12 +152,16 @@ 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 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 @@ -715,7 +719,15 @@ class ChordEvent (NestedMusic): 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)] @@ -753,7 +765,9 @@ class ChordEvent (NestedMusic): 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 @@ -849,9 +863,9 @@ class BeamEvent (SpanEvent): 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): @@ -887,10 +901,10 @@ class OctaveShiftEvent (SpanEvent): 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): @@ -923,12 +937,12 @@ class ArpeggioEvent(Event): 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') @@ -1085,6 +1099,60 @@ class FretEvent (MarkupEvent): else: return '' +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) @@ -1271,6 +1339,106 @@ 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: + 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): @@ -1381,6 +1549,12 @@ class Staff (StaffGroup): 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: @@ -1388,7 +1562,7 @@ class Staff (StaffGroup): 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: @@ -1400,6 +1574,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):