6 from rational import Rational
9 def escape_instrument_string (input_string):
10 retstring = string.replace (input_string, "\"", "\\\"")
11 if re.match ('.*[\r\n]+.*', retstring):
12 rx = re.compile (r'[\n\r]+')
13 strings = rx.split (retstring)
14 retstring = "\\markup { \\column { "
16 retstring += "\\line {\"" + s + "\"} "
19 retstring = "\"" + retstring + "\""
22 class Output_stack_element:
24 self.factor = Rational (1)
26 o = Output_stack_element()
27 o.factor = self.factor
32 """A class that takes care of formatting (eg.: indenting) a
33 Music expression as a .ly file.
36 ## TODO: support for \relative.
42 self._file = sys.stdout
44 self._output_state_stack = [Output_stack_element()]
45 self._skipspace = False
46 self._last_duration = None
48 def set_file (self, file):
51 def dump_version (self):
53 self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
56 def get_indent (self):
57 return self._nesting * self._indent
60 last = self._output_state_stack[-1]
61 self._output_state_stack.append (last.copy())
63 def add_factor (self, factor):
65 self._output_state_stack[-1].factor *= factor
68 del self._output_state_stack[-1]
69 if not self._output_state_stack:
72 def duration_factor (self):
73 return self._output_state_stack[-1].factor
75 def print_verbatim (self, str):
78 def unformatted_output (self, str):
79 # don't indent on \< and indent only once on <<
80 self._nesting += ( str.count ('<')
81 - str.count ('\<') - str.count ('<<')
83 self._nesting -= ( str.count ('>') - str.count ('\>') - str.count ('>>')
84 - str.count ('->') - str.count ('_>')
87 self.print_verbatim (str)
89 def print_duration_string (self, str):
90 if self._last_duration == str:
93 self.unformatted_output (str)
95 def add_word (self, str):
96 if (len (str) + 1 + len (self._line) > self._line_len):
98 self._skipspace = True
100 if not self._skipspace:
102 self.unformatted_output (str)
103 self._skipspace = False
106 self._file.write (self._line + '\n')
107 self._line = ' ' * self._indent * self._nesting
108 self._skipspace = True
110 def skipspace (self):
111 self._skipspace = True
113 def __call__(self, arg):
116 def dump (self, str):
118 self._skipspace = False
119 self.unformatted_output (str)
121 words = string.split (str)
134 self.duration_log = 0
136 self.factor = Rational (1)
138 def lisp_expression (self):
139 return '(ly:make-duration %d %d %d %d)' % (self.duration_log,
141 self.factor.numerator (),
142 self.factor.denominator ())
145 def ly_expression (self, factor = None):
149 str = '%d%s' % (1 << self.duration_log, '.'*self.dots)
151 if factor <> Rational (1,1):
152 if factor.denominator () <> 1:
153 str += '*%d/%d' % (factor.numerator (), factor.denominator ())
155 str += '*%d' % factor.numerator ()
159 def print_ly (self, outputter):
160 str = self.ly_expression (self.factor / outputter.duration_factor ())
161 outputter.print_duration_string (str)
164 return self.ly_expression()
169 d.duration_log = self.duration_log
170 d.factor = self.factor
173 def get_length (self):
174 dot_fact = Rational( (1 << (1 + self.dots))-1,
177 log = abs (self.duration_log)
179 if self.duration_log < 0:
180 base = Rational (dur)
182 base = Rational (1, dur)
184 return base * dot_fact * self.factor
194 return self.ly_expression()
196 def transposed (self, interval):
198 c.alteration += interval.alteration
199 c.step += interval.step
200 c.octave += interval.octave
203 target_st = self.semitones() + interval.semitones()
204 c.alteration += target_st - c.semitones()
211 c.octave += c.step / 7
214 def lisp_expression (self):
215 return '(ly:make-pitch %d %d %d)' % (self.octave,
221 p.alteration = self.alteration
223 p.octave = self.octave
227 return self.step + self.octave *7
229 def semitones (self):
230 return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
232 def ly_step_expression (self):
233 str = 'cdefgab'[self.step]
234 if self.alteration > 0:
235 str += 'is'* (self.alteration)
236 elif self.alteration < 0:
237 str += 'es'* (-self.alteration)
239 return str.replace ('aes', 'as').replace ('ees', 'es')
241 def ly_expression (self):
242 str = self.ly_step_expression ()
244 str += "'" * (self.octave + 1)
245 elif self.octave < -1:
246 str += "," * (-self.octave - 1)
250 def print_ly (self, outputter):
251 outputter (self.ly_expression())
256 self.start = Rational (0)
258 self.identifier = None
260 def get_length(self):
263 def get_properties (self):
266 def has_children (self):
269 def get_index (self):
271 return self.parent.elements.index (self)
275 return self.__class__.__name__
277 def lisp_expression (self):
280 props = self.get_properties ()
282 return "(make-music '%s %s)" % (name, props)
284 def set_start (self, start):
287 def find_first (self, predicate):
292 def print_comment (self, printer, text = None):
303 lines = string.split (text, '\n')
306 printer.unformatted_output ('% ' + l)
310 def print_with_identifier (self, printer):
312 printer ("\\%s" % self.identifier)
314 self.print_ly (printer)
316 def print_ly (self, printer):
317 printer (self.ly_expression ())
319 class MusicWrapper (Music):
323 def print_ly (self, func):
324 self.element.print_ly (func)
326 class ModeChangingMusicWrapper (MusicWrapper):
328 MusicWrapper.__init__ (self)
329 self.mode = 'notemode'
331 def print_ly (self, func):
332 func ('\\%s' % self.mode)
333 MusicWrapper.print_ly (self, func)
335 class TimeScaledMusic (MusicWrapper):
336 def print_ly (self, func):
337 func ('\\times %d/%d ' %
338 (self.numerator, self.denominator))
339 func.add_factor (Rational (self.numerator, self.denominator))
340 MusicWrapper.print_ly (self, func)
343 class NestedMusic(Music):
345 Music.__init__ (self)
348 def append (self, what):
350 self.elements.append (what)
352 def has_children (self):
355 def insert_around (self, succ, elt, dir):
356 assert elt.parent == None
357 assert succ == None or succ in self.elements
362 idx = self.elements.index (succ)
369 idx = len (self.elements)
371 self.elements.insert (idx, elt)
374 def get_properties (self):
375 return ("'elements (list %s)"
376 % string.join (map (lambda x: x.lisp_expression(),
379 def get_subset_properties (self, predicate):
380 return ("'elements (list %s)"
381 % string.join (map (lambda x: x.lisp_expression(),
382 filter ( predicate, self.elements))))
383 def get_neighbor (self, music, dir):
384 assert music.parent == self
385 idx = self.elements.index (music)
387 idx = min (idx, len (self.elements) -1)
390 return self.elements[idx]
392 def delete_element (self, element):
393 assert element in self.elements
395 self.elements.remove (element)
396 element.parent = None
398 def set_start (self, start):
400 for e in self.elements:
403 def find_first (self, predicate):
404 r = Music.find_first (self, predicate)
408 for e in self.elements:
409 r = e.find_first (predicate)
414 class SequentialMusic (NestedMusic):
415 def get_last_event_chord (self):
417 at = len( self.elements ) - 1
419 not isinstance (self.elements[at], EventChord) and
420 not isinstance (self.elements[at], BarLine)):
423 if (at >= 0 and isinstance (self.elements[at], EventChord)):
424 value = self.elements[at]
427 def print_ly (self, printer, newline = True):
430 self.print_comment (printer)
434 for e in self.elements:
441 def lisp_sub_expression (self, pred):
445 props = self.get_subset_properties (pred)
447 return "(make-music '%s %s)" % (name, props)
449 def set_start (self, start):
450 for e in self.elements:
452 start += e.get_length()
456 self.repeat_type = "volta"
457 self.repeat_count = 2
460 def set_music (self, music):
461 if isinstance (music, Music):
463 elif isinstance (music, list):
464 self.music = SequentialMusic ()
465 self.music.elements = music
467 sys.stderr.write ("WARNING: Unable to set the music %s for the repeat %s" % (music, self))
468 def add_ending (self, music):
469 self.endings.append (music)
470 def print_ly (self, printer):
471 printer.dump ('\\repeat %s %s' % (self.repeat_type, self.repeat_count))
473 self.music.print_ly (printer)
475 sys.stderr.write ("WARNING: Encountered repeat without body\n")
478 printer.dump ('\\alternative {')
479 for e in self.endings:
486 self.lyrics_syllables = []
488 def print_ly (self, printer):
489 printer.dump ("\lyricmode {")
490 for l in self.lyrics_syllables:
491 printer.dump ( "%s " % l )
494 def ly_expression (self):
495 lstr = "\lyricmode {\n "
496 for l in self.lyrics_syllables:
504 self.header_fields = {}
505 def set_field (self, field, value):
506 self.header_fields[field] = value
508 def print_ly (self, printer):
509 printer.dump ("\header {")
511 for (k,v) in self.header_fields.items ():
513 printer.dump ('%s = %s' % (k,v))
522 class EventChord (NestedMusic):
524 NestedMusic.__init__ (self)
525 self.grace_elements = None
526 self.grace_type = None
527 def append_grace (self, element):
529 if not self.grace_elements:
530 self.grace_elements = SequentialMusic ()
531 self.grace_elements.append (element)
533 def get_length (self):
535 for e in self.elements:
536 l = max(l, e.get_length())
539 def print_ly (self, printer):
540 note_events = [e for e in self.elements if
541 isinstance (e, NoteEvent)]
543 rest_events = [e for e in self.elements if
544 isinstance (e, RhythmicEvent)
545 and not isinstance (e, NoteEvent)]
547 other_events = [e for e in self.elements if
548 not isinstance (e, RhythmicEvent)]
550 if self.grace_elements and self.elements:
552 printer ('\\%s' % self.grace_type)
555 # don't print newlines after the { and } braces
556 self.grace_elements.print_ly (printer, False)
559 rest_events[0].print_ly (printer)
560 elif len (note_events) == 1:
561 note_events[0].print_ly (printer)
563 pitches = [x.pitch.ly_expression () for x in note_events]
564 printer ('<%s>' % string.join (pitches))
565 note_events[0].duration.print_ly (printer)
569 for e in other_events:
572 self.print_comment (printer)
574 class Partial (Music):
576 Music.__init__ (self)
578 def print_ly (self, printer):
580 printer.dump ("\\partial %s" % self.partial.ly_expression ())
582 class BarLine (Music):
584 Music.__init__ (self)
588 def print_ly (self, printer):
589 bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': ":",
590 'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
591 'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'",
592 'short': "'", 'none': "" }.get (self.type, None)
593 if bar_symbol <> None:
594 printer.dump ('\\bar "%s"' % bar_symbol)
598 if self.bar_number > 0 and (self.bar_number % 10) == 0:
599 printer.dump ("\\barNumberCheck #%d " % self.bar_number)
601 printer.print_verbatim (' %% %d' % self.bar_number)
604 def ly_expression (self):
610 class SpanEvent (Event):
612 Event.__init__ (self)
613 self.span_direction = 0 # start/stop
614 self.line_type = 'solid'
615 self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
616 self.size = 0 # size of e.g. ocrave shift
617 def wait_for_note (self):
619 def get_properties(self):
620 return "'span-direction %d" % self.span_direction
621 def set_span_type (self, type):
622 self.span_type = type
624 class SlurEvent (SpanEvent):
625 def ly_expression (self):
628 # TODO: setting dashed/dotted line style does not work, because that
629 # command needs to be written before the note, not when the
630 # event is observed after the note!
631 #before = {'dotted': '\\slurDotted',
632 # 'dashed' : '\\slurDashed'}.get (self.line_type, '')
634 #after = '\\slurSolid'
636 return {-1: before + '(' + after,
637 1:')'}.get (self.span_direction, '')
639 class BeamEvent (SpanEvent):
640 def ly_expression (self):
642 1:']'}.get (self.span_direction, '')
644 class PedalEvent (SpanEvent):
645 def ly_expression (self):
646 return {-1: '\\sustainDown',
647 1:'\\sustainUp'}.get (self.span_direction, '')
649 # type==-1 means octave up, type==-2 means octave down
650 class OctaveShiftEvent (SpanEvent):
651 def wait_for_note (self):
653 def set_span_type (self, type):
654 self.span_type = {'up': 1, 'down': -1}.get (type, 0)
655 def ly_octave_shift_indicator (self):
656 # convert 8/15 to lilypond indicators (+-1/+-2)
657 value = {8: 1, 15: 2}.get (self.size, 0)
658 # negative values go up!
659 value *= -1*self.span_type
661 def ly_expression (self):
662 dir = self.ly_octave_shift_indicator ()
665 value = '#(set-octavation %s)' % dir
668 1: '#(set-octavation 0)'}.get (self.span_direction, '')
670 class TrillSpanEvent (SpanEvent):
671 def ly_expression (self):
672 return {-1: '\\startTrillSpan',
673 0: '', # no need to write out anything for type='continue'
674 1:'\\stopTrillSpan'}.get (self.span_direction, '')
676 class GlissandoEvent (SpanEvent):
677 def ly_expression (self):
679 # TODO: wavy-line glissandos don't work, becasue the style has to be
680 # set before the note, at the \glissando it's already too late!
681 #if self.line_type == 'wavy':
682 #style = "\once\override Glissando #'style = #'zigzag"
683 # In lilypond, glissando is NOT a spanner, unlike MusicXML.
684 return {-1: style + '\\glissando',
685 1:''}.get (self.span_direction, '')
687 class ArpeggioEvent(Event):
689 Event.__init__ (self)
691 def wait_for_note (self):
693 def ly_expression (self):
694 # TODO: Use self.direction for up/down arpeggios
695 return ('\\arpeggio')
698 class TieEvent(Event):
699 def ly_expression (self):
703 class HairpinEvent (SpanEvent):
704 def set_span_type (self, type):
705 self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
706 def hairpin_to_ly (self):
707 if self.span_direction == 1:
710 return {1: '\<', -1: '\>'}.get (self.span_type, '')
712 def ly_expression (self):
713 return self.hairpin_to_ly ()
715 def print_ly (self, printer):
716 val = self.hairpin_to_ly ()
722 class DynamicsEvent (Event):
725 self.available_commands = [ "ppppp", "pppp", "ppp", "pp", "p",
727 "f", "ff", "fff", "ffff",
728 "fp", "sf", "sff", "sp", "spp", "sfz", "rfz" ];
729 def wait_for_note (self):
731 def ly_expression (self):
732 if self.type == None:
734 elif self.type in self.available_commands:
735 return '\%s' % self.type
737 return '-\markup{ \dynamic %s }' % self.type
739 def print_ly (self, printer):
740 if self.type == None:
742 elif self.type in self.available_commands:
743 printer.dump ("\\%s" % self.type)
745 printer.dump ("-\\markup{ \\dynamic %s }" % self.type)
748 class TextEvent (Event):
751 self.force_direction = None
753 def wait_for_note (self):
756 def direction_mod (self):
757 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
759 def ly_expression (self):
760 base_string = '%s\"%s\"'
762 base_string = '%s\markup{ ' + self.markup + ' {%s} }'
763 return base_string % (self.direction_mod (), self.text)
765 class ArticulationEvent (Event):
768 self.force_direction = None
769 def wait_for_note (self):
772 def direction_mod (self):
773 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '')
775 def ly_expression (self):
776 return '%s\\%s' % (self.direction_mod (), self.type)
778 class ShortArticulationEvent (ArticulationEvent):
779 def direction_mod (self):
781 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
782 def ly_expression (self):
784 return '%s%s' % (self.direction_mod (), self.type)
788 class NoDirectionArticulationEvent (ArticulationEvent):
789 def ly_expression (self):
791 return '\\%s' % self.type
795 class MarkupEvent (ShortArticulationEvent):
797 ArticulationEvent.__init__ (self)
799 def ly_expression (self):
801 return "%s\\markup { %s }" % (self.direction_mod (), self.contents)
805 class FretEvent (MarkupEvent):
807 MarkupEvent.__init__ (self)
808 self.force_direction = 1
813 def ly_expression (self):
815 if self.strings <> 6:
816 val += "w:%s;" % self.strings
818 val += "h:%s;" % self.frets
819 if self.barre and len (self.barre) >= 3:
820 val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2])
821 have_fingering = False
822 for i in self.elements:
824 val += "%s-%s" % (i[0], i[1])
826 have_fingering = True
832 return "%s\\markup { \\fret-diagram #\"%s\" }" % (self.direction_mod (), val)
836 class TremoloEvent (ArticulationEvent):
838 Event.__init__ (self)
841 def ly_expression (self):
843 if self.bars and self.bars > 0:
844 str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
847 class BendEvent (ArticulationEvent):
849 Event.__init__ (self)
851 def ly_expression (self):
853 return "-\\bendAfter #%s" % self.alter
857 class RhythmicEvent(Event):
859 Event.__init__ (self)
860 self.duration = Duration()
862 def get_length (self):
863 return self.duration.get_length()
865 def get_properties (self):
866 return ("'duration %s"
867 % self.duration.lisp_expression ())
869 class RestEvent (RhythmicEvent):
871 RhythmicEvent.__init__ (self)
873 def ly_expression (self):
875 return "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
877 return 'r%s' % self.duration.ly_expression ()
879 def print_ly (self, printer):
881 self.pitch.print_ly (printer)
882 self.duration.print_ly (printer)
886 self.duration.print_ly (printer)
888 class SkipEvent (RhythmicEvent):
889 def ly_expression (self):
890 return 's%s' % self.duration.ly_expression ()
892 class NoteEvent(RhythmicEvent):
894 RhythmicEvent.__init__ (self)
896 self.drum_type = None
897 self.cautionary = False
898 self.forced_accidental = False
900 def get_properties (self):
901 str = RhythmicEvent.get_properties (self)
904 str += self.pitch.lisp_expression ()
906 str += "'drum-type '%s" % self.drum_type
910 def pitch_mods (self):
914 if self.forced_accidental:
919 def ly_expression (self):
921 return '%s%s%s' % (self.pitch.ly_expression (),
923 self.duration.ly_expression ())
925 return '%s%s' (self.drum_type,
926 self.duration.ly_expression ())
928 def print_ly (self, printer):
930 self.pitch.print_ly (printer)
931 printer (self.pitch_mods ())
933 printer (self.drum_type)
935 self.duration.print_ly (printer)
937 class KeySignatureChange (Music):
939 Music.__init__ (self)
944 def ly_expression (self):
945 return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
948 def lisp_expression (self):
949 pairs = ['(%d . %d)' % (i , self.scale[i]) for i in range (0,7)]
950 scale_str = ("'(%s)" % string.join (pairs))
952 return """ (make-music 'KeyChangeEvent
953 'pitch-alist %s) """ % scale_str
955 class TimeSignatureChange (Music):
957 Music.__init__ (self)
958 self.fraction = (4,4)
959 def ly_expression (self):
960 return '\\time %d/%d ' % self.fraction
962 class ClefChange (Music):
964 Music.__init__ (self)
969 def octave_modifier (self):
970 return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
971 def clef_name (self):
972 return {('G', 2): "treble",
975 ('C', 2): "mezzosoprano",
978 ('C', 5): "baritone",
979 ('F', 3): "varbaritone",
982 ("percussion", 2): "percussion",
983 ("TAB", 5): "tab"}.get ((self.type, self.position), None)
984 def ly_expression (self):
985 return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
988 "G": ("clefs.G", -2, -6),
989 "C": ("clefs.C", 0, 0),
990 "F": ("clefs.F", 2, 6),
993 def lisp_expression (self):
995 (glyph, pos, c0) = self.clef_dict[self.type]
999 (make-music 'SequentialMusic
1002 (make-property-set 'clefGlyph "%s") 'Staff)
1004 (make-property-set 'clefPosition %d) 'Staff)
1006 (make-property-set 'middleCPosition %d) 'Staff)))
1007 """ % (glyph, pos, c0)
1011 class StaffChange (Music):
1012 def __init__ (self, staff):
1013 Music.__init__ (self)
1015 def ly_expression (self):
1017 return "\\change Staff=\"%s\"" % self.staff
1022 class MultiMeasureRest(Music):
1024 def lisp_expression (self):
1027 'MultiMeasureRestMusicGroup
1029 (list (make-music (quote BarCheck))
1034 'MultiMeasureRestEvent
1037 (make-music (quote BarCheck))))
1038 """ % self.duration.lisp_expression ()
1040 def ly_expression (self):
1041 return 'R%s' % self.duration.ly_expression ()
1045 def __init__ (self, command = "StaffGroup"):
1046 self.stafftype = command
1048 self.instrument_name = None
1049 self.short_instrument_name = None
1053 self.is_group = True
1054 # part_information is a list with entries of the form
1055 # [staffid, voicelist]
1056 # where voicelist is a list with entries of the form
1057 # [voiceid1, [lyricsid11, lyricsid12,...] ]
1058 self.part_information = None
1060 def append_staff (self, staff):
1061 self.children.append (staff)
1063 def set_part_information (self, part_name, staves_info):
1064 if part_name == self.id:
1065 self.part_information = staves_info
1067 for c in self.children:
1068 c.set_part_information (part_name, staves_info)
1070 def print_ly_contents (self, printer):
1071 for c in self.children:
1073 c.print_ly (printer)
1074 def print_ly_overrides (self, printer):
1076 needs_with |= self.spanbar == "no"
1077 needs_with |= self.instrument_name != None
1078 needs_with |= self.short_instrument_name != None
1079 needs_with |= (self.symbol != None) and (self.symbol != "bracket")
1081 printer.dump ("\\with {")
1082 if self.instrument_name or self.short_instrument_name:
1083 printer.dump ("\\consists \"Instrument_name_engraver\"")
1084 if self.spanbar == "no":
1085 printer.dump ("\\override SpanBar #'transparent = ##t")
1086 brack = {"brace": "SystemStartBrace",
1088 "line": "SystemStartSquare"}.get (self.symbol, None)
1090 printer.dump ("systemStartDelimiter = #'%s" % brack)
1093 def print_ly (self, printer):
1095 printer.dump ("\\new %s" % self.stafftype)
1096 self.print_ly_overrides (printer)
1099 if self.stafftype and self.instrument_name:
1100 printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
1101 escape_instrument_string (self.instrument_name)))
1103 if self.stafftype and self.short_instrument_name:
1104 printer.dump ("\\set %s.shortInstrumentName = %s" % (self.stafftype,
1105 escape_instrument_string (self.short_instrument_name)))
1107 self.print_ly_contents (printer)
1113 class Staff (StaffGroup):
1114 def __init__ (self):
1115 StaffGroup.__init__ (self, "Staff")
1116 self.is_group = False
1119 def print_ly_overrides (self, printer):
1122 def print_ly_contents (self, printer):
1123 if not self.id or not self.part_information:
1126 for [staff_id, voices] in self.part_information:
1128 printer ('\\context %s = "%s" << ' % (self.stafftype, staff_id))
1130 printer ('\\context %s << ' % self.stafftype)
1133 nr_voices = len (voices)
1134 for [v, lyrics] in voices:
1136 voice_count_text = ''
1138 voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo',
1139 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
1140 printer ('\\context Voice = "%s" {%s \\%s }' % (v,voice_count_text,v))
1144 printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
1148 def print_ly (self, printer):
1149 if self.part_information and len (self.part_information) > 1:
1150 self.stafftype = "PianoStaff"
1151 StaffGroup.print_ly (self, printer)
1156 bflat.alteration = -1
1166 print bflat.semitones()
1167 print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
1168 print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
1170 print bflat.semitones(), 'down'
1171 print bflat.transposed (down)
1172 print bflat.transposed (down).transposed (down)
1173 print bflat.transposed (down).transposed (down).transposed (down)
1177 def test_printer ():
1185 m = SequentialMusic()
1186 m.append (make_note ())
1187 m.append (make_note ())
1188 m.append (make_note ())
1191 t = TimeScaledMusic ()
1197 m = SequentialMusic ()
1198 m.append (make_tup ())
1199 m.append (make_tup ())
1200 m.append (make_tup ())
1202 printer = Output_printer()
1203 m.print_ly (printer)
1207 m = SequentialMusic()
1211 n.duration.duration_log = l
1213 evc.insert_around (None, n, 0)
1214 m.insert_around (None, evc, 0)
1218 n.duration.duration_log = l
1220 evc.insert_around (None, n, 0)
1221 m.insert_around (None, evc, 0)
1225 n.duration.duration_log = l
1227 evc.insert_around (None, n, 0)
1228 m.insert_around (None, evc, 0)
1232 m.insert_around (None, evc, 0)
1237 tonic.alteration = -2
1238 n = KeySignatureChange()
1239 n.tonic=tonic.copy()
1240 n.scale = [0, 0, -2, 0, 0,-2,-2]
1242 evc.insert_around (None, n, 0)
1243 m.insert_around (None, evc, 0)
1248 if __name__ == '__main__':
1254 expr.set_start (Rational (0))
1255 print expr.ly_expression()
1256 start = Rational (0,4)
1257 stop = Rational (4,2)
1258 def sub(x, start=start, stop=stop):
1259 ok = x.start >= start and x.start +x.get_length() <= stop
1262 print expr.lisp_sub_expression(sub)