X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=python%2Fmusicexp.py;h=c653c5cb7944e664c9130caebc66a5e280f199a0;hb=9eaa5cfbb25d1742e44396281ceff2ba67b7c8ef;hp=3219c689d249e6a50520707945b4b1ddb83cf711;hpb=8209aff7f2ebbbe437faa05ea1b7d92a27a15806;p=lilypond.git diff --git a/python/musicexp.py b/python/musicexp.py index 3219c689d2..c653c5cb79 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 @@ -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) @@ -1270,6 +1338,56 @@ class StaffChange (Music): else: 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: + dm = self.duration_to_markup (self.baseduration) + contents = "\"(\" %s = %s \")\"" % (dm, self.beats) + res += self.tempo_markup_template() % contents + 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) @@ -1318,7 +1436,7 @@ class FiguredBassEvent (NestedMusic): notes.append (x.ly_expression ()) contents = string.join (notes) if self.parentheses: - contents = '[%]' % contents + contents = '[%s]' % contents printer ('<%s>' % contents) self.duration.print_ly (printer) @@ -1433,6 +1551,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: @@ -1440,7 +1564,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: @@ -1452,6 +1576,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):