6 from rational import Rational
9 def escape_instrument_string (input_string):
10 retstring = string.replace (input_string, "\"", "\\\"")
11 if re.match ('.*\n.*', retstring):
12 strings = retstring.split ('\r\n')
13 retstring = "\\markup { \\column { "
15 retstring += "\\line {\"" + s + "\"} "
18 retstring = "\"" + retstring + "\""
21 class Output_stack_element:
23 self.factor = Rational (1)
25 o = Output_stack_element()
26 o.factor = self.factor
31 """A class that takes care of formatting (eg.: indenting) a
32 Music expression as a .ly file.
35 ## TODO: support for \relative.
41 self._file = sys.stdout
43 self._output_state_stack = [Output_stack_element()]
44 self._skipspace = False
45 self._last_duration = None
47 def set_file (self, file):
50 def dump_version (self):
52 self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
55 def get_indent (self):
56 return self._nesting * self._indent
59 last = self._output_state_stack[-1]
60 self._output_state_stack.append (last.copy())
62 def add_factor (self, factor):
64 self._output_state_stack[-1].factor *= factor
67 del self._output_state_stack[-1]
68 if not self._output_state_stack:
71 def duration_factor (self):
72 return self._output_state_stack[-1].factor
74 def print_verbatim (self, str):
77 def unformatted_output (self, str):
78 # don't indent on \< and indent only once on <<
79 self._nesting += ( str.count ('<')
80 - str.count ('\<') - str.count ('<<')
82 self._nesting -= ( str.count ('>') - str.count ('\>') - str.count ('>>')
83 - str.count ('->') - str.count ('_>')
86 self.print_verbatim (str)
88 def print_duration_string (self, str):
89 if self._last_duration == str:
92 self.unformatted_output (str)
94 def add_word (self, str):
95 if (len (str) + 1 + len (self._line) > self._line_len):
97 self._skipspace = True
99 if not self._skipspace:
101 self.unformatted_output (str)
102 self._skipspace = False
105 self._file.write (self._line + '\n')
106 self._line = ' ' * self._indent * self._nesting
107 self._skipspace = True
109 def skipspace (self):
110 self._skipspace = True
112 def __call__(self, arg):
115 def dump (self, str):
117 self._skipspace = False
118 self.unformatted_output (str)
120 words = string.split (str)
133 self.duration_log = 0
135 self.factor = Rational (1)
137 def lisp_expression (self):
138 return '(ly:make-duration %d %d %d %d)' % (self.duration_log,
140 self.factor.numerator (),
141 self.factor.denominator ())
144 def ly_expression (self, factor = None):
148 str = '%d%s' % (1 << self.duration_log, '.'*self.dots)
150 if factor <> Rational (1,1):
151 if factor.denominator () <> 1:
152 str += '*%d/%d' % (factor.numerator (), factor.denominator ())
154 str += '*%d' % factor.numerator ()
158 def print_ly (self, outputter):
159 str = self.ly_expression (self.factor / outputter.duration_factor ())
160 outputter.print_duration_string (str)
163 return self.ly_expression()
168 d.duration_log = self.duration_log
169 d.factor = self.factor
172 def get_length (self):
173 dot_fact = Rational( (1 << (1 + self.dots))-1,
176 log = abs (self.duration_log)
178 if self.duration_log < 0:
179 base = Rational (dur)
181 base = Rational (1, dur)
183 return base * dot_fact * self.factor
193 return self.ly_expression()
195 def transposed (self, interval):
197 c.alteration += interval.alteration
198 c.step += interval.step
199 c.octave += interval.octave
202 target_st = self.semitones() + interval.semitones()
203 c.alteration += target_st - c.semitones()
210 c.octave += c.step / 7
213 def lisp_expression (self):
214 return '(ly:make-pitch %d %d %d)' % (self.octave,
220 p.alteration = self.alteration
222 p.octave = self.octave
226 return self.step + self.octave *7
228 def semitones (self):
229 return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
231 def ly_step_expression (self):
232 str = 'cdefgab'[self.step]
233 if self.alteration > 0:
234 str += 'is'* (self.alteration)
235 elif self.alteration < 0:
236 str += 'es'* (-self.alteration)
238 return str.replace ('aes', 'as').replace ('ees', 'es')
240 def ly_expression (self):
241 str = self.ly_step_expression ()
243 str += "'" * (self.octave + 1)
244 elif self.octave < -1:
245 str += "," * (-self.octave - 1)
249 def print_ly (self, outputter):
250 outputter (self.ly_expression())
255 self.start = Rational (0)
257 self.identifier = None
259 def get_length(self):
262 def get_properties (self):
265 def has_children (self):
268 def get_index (self):
270 return self.parent.elements.index (self)
274 return self.__class__.__name__
276 def lisp_expression (self):
279 props = self.get_properties ()
281 return "(make-music '%s %s)" % (name, props)
283 def set_start (self, start):
286 def find_first (self, predicate):
291 def print_comment (self, printer, text = None):
302 lines = string.split (text, '\n')
305 printer.unformatted_output ('% ' + l)
309 def print_with_identifier (self, printer):
311 printer ("\\%s" % self.identifier)
313 self.print_ly (printer)
315 def print_ly (self, printer):
316 printer (self.ly_expression ())
318 class MusicWrapper (Music):
322 def print_ly (self, func):
323 self.element.print_ly (func)
325 class ModeChangingMusicWrapper (MusicWrapper):
327 MusicWrapper.__init__ (self)
328 self.mode = 'notemode'
330 def print_ly (self, func):
331 func ('\\%s' % self.mode)
332 MusicWrapper.print_ly (self, func)
334 class TimeScaledMusic (MusicWrapper):
335 def print_ly (self, func):
336 func ('\\times %d/%d ' %
337 (self.numerator, self.denominator))
338 func.add_factor (Rational (self.numerator, self.denominator))
339 MusicWrapper.print_ly (self, func)
342 class NestedMusic(Music):
344 Music.__init__ (self)
347 def append (self, what):
349 self.elements.append (what)
351 def has_children (self):
354 def insert_around (self, succ, elt, dir):
355 assert elt.parent == None
356 assert succ == None or succ in self.elements
361 idx = self.elements.index (succ)
368 idx = len (self.elements)
370 self.elements.insert (idx, elt)
373 def get_properties (self):
374 return ("'elements (list %s)"
375 % string.join (map (lambda x: x.lisp_expression(),
378 def get_subset_properties (self, predicate):
379 return ("'elements (list %s)"
380 % string.join (map (lambda x: x.lisp_expression(),
381 filter ( predicate, self.elements))))
382 def get_neighbor (self, music, dir):
383 assert music.parent == self
384 idx = self.elements.index (music)
386 idx = min (idx, len (self.elements) -1)
389 return self.elements[idx]
391 def delete_element (self, element):
392 assert element in self.elements
394 self.elements.remove (element)
395 element.parent = None
397 def set_start (self, start):
399 for e in self.elements:
402 def find_first (self, predicate):
403 r = Music.find_first (self, predicate)
407 for e in self.elements:
408 r = e.find_first (predicate)
413 class SequentialMusic (NestedMusic):
414 def get_last_event_chord (self):
416 at = len( self.elements ) - 1
418 not isinstance (self.elements[at], EventChord) and
419 not isinstance (self.elements[at], BarLine)):
422 if (at >= 0 and isinstance (self.elements[at], EventChord)):
423 value = self.elements[at]
426 def print_ly (self, printer, newline = True):
429 self.print_comment (printer)
433 for e in self.elements:
440 def lisp_sub_expression (self, pred):
444 props = self.get_subset_properties (pred)
446 return "(make-music '%s %s)" % (name, props)
448 def set_start (self, start):
449 for e in self.elements:
451 start += e.get_length()
455 self.repeat_type = "volta"
456 self.repeat_count = 2
459 def set_music (self, music):
460 if isinstance (music, Music):
462 elif isinstance (music, list):
463 self.music = SequentialMusic ()
464 self.music.elements = music
466 sys.stderr.write ("WARNING: Unable to set the music %s for the repeat %s" % (music, self))
467 def add_ending (self, music):
468 self.endings.append (music)
469 def print_ly (self, printer):
470 printer.dump ('\\repeat %s %s' % (self.repeat_type, self.repeat_count))
472 self.music.print_ly (printer)
474 sys.stderr.write ("WARNING: Encountered repeat without body\n")
477 printer.dump ('\\alternative {')
478 for e in self.endings:
485 self.lyrics_syllables = []
487 def print_ly (self, printer):
488 printer.dump ("\lyricmode {")
489 for l in self.lyrics_syllables:
490 printer.dump ( "%s " % l )
493 def ly_expression (self):
494 lstr = "\lyricmode {\n "
495 for l in self.lyrics_syllables:
503 self.header_fields = {}
504 def set_field (self, field, value):
505 self.header_fields[field] = value
507 def print_ly (self, printer):
508 printer.dump ("\header {")
510 for (k,v) in self.header_fields.items ():
512 printer.dump ('%s = %s' % (k,v))
521 class EventChord (NestedMusic):
523 NestedMusic.__init__ (self)
524 self.grace_elements = None
525 self.grace_type = None
526 def append_grace (self, element):
528 if not self.grace_elements:
529 self.grace_elements = SequentialMusic ()
530 self.grace_elements.append (element)
532 def get_length (self):
534 for e in self.elements:
535 l = max(l, e.get_length())
538 def print_ly (self, printer):
539 note_events = [e for e in self.elements if
540 isinstance (e, NoteEvent)]
542 rest_events = [e for e in self.elements if
543 isinstance (e, RhythmicEvent)
544 and not isinstance (e, NoteEvent)]
546 other_events = [e for e in self.elements if
547 not isinstance (e, RhythmicEvent)]
549 if self.grace_elements and self.elements:
551 printer ('\\%s' % self.grace_type)
554 # don't print newlines after the { and } braces
555 self.grace_elements.print_ly (printer, False)
558 rest_events[0].print_ly (printer)
559 elif len (note_events) == 1:
560 note_events[0].print_ly (printer)
562 pitches = [x.pitch.ly_expression () for x in note_events]
563 printer ('<%s>' % string.join (pitches))
564 note_events[0].duration.print_ly (printer)
568 for e in other_events:
571 self.print_comment (printer)
573 class Partial (Music):
575 Music.__init__ (self)
577 def print_ly (self, printer):
579 printer.dump ("\\partial %s" % self.partial.ly_expression ())
581 class BarLine (Music):
583 Music.__init__ (self)
587 def print_ly (self, printer):
588 bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': ":",
589 'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
590 'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'",
591 'short': "'", 'none': "" }.get (self.type, None)
592 if bar_symbol <> None:
593 printer.dump ('\\bar "%s"' % bar_symbol)
597 if self.bar_number > 0 and (self.bar_number % 10) == 0:
598 printer.dump ("\\barNumberCheck #%d " % self.bar_number)
600 printer.print_verbatim (' %% %d' % self.bar_number)
603 def ly_expression (self):
609 class SpanEvent (Event):
611 Event.__init__ (self)
612 self.span_direction = 0 # start/stop
613 self.line_type = 'solid'
614 self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
615 self.size = 0 # size of e.g. ocrave shift
616 def wait_for_note (self):
618 def get_properties(self):
619 return "'span-direction %d" % self.span_direction
620 def set_span_type (self, type):
621 self.span_type = type
623 class SlurEvent (SpanEvent):
624 def ly_expression (self):
627 # TODO: setting dashed/dotted line style does not work, because that
628 # command needs to be written before the note, not when the
629 # event is observed after the note!
630 #before = {'dotted': '\\slurDotted',
631 # 'dashed' : '\\slurDashed'}.get (self.line_type, '')
633 #after = '\\slurSolid'
635 return {-1: before + '(' + after,
636 1:')'}.get (self.span_direction, '')
638 class BeamEvent (SpanEvent):
639 def ly_expression (self):
641 1:']'}.get (self.span_direction, '')
643 class PedalEvent (SpanEvent):
644 def ly_expression (self):
645 return {-1: '\\sustainDown',
646 1:'\\sustainUp'}.get (self.span_direction, '')
648 # type==-1 means octave up, type==-2 means octave down
649 class OctaveShiftEvent (SpanEvent):
650 def wait_for_note (self):
652 def set_span_type (self, type):
653 self.span_type = {'up': 1, 'down': -1}.get (type, 0)
654 def ly_octave_shift_indicator (self):
655 # convert 8/15 to lilypond indicators (+-1/+-2)
656 value = {8: 1, 15: 2}.get (self.size, 0)
657 # negative values go up!
658 value *= -1*self.span_type
660 def ly_expression (self):
661 dir = self.ly_octave_shift_indicator ()
664 value = '#(set-octavation %s)' % dir
667 1: '#(set-octavation 0)'}.get (self.span_direction, '')
669 class TrillSpanEvent (SpanEvent):
670 def ly_expression (self):
671 return {-1: '\\startTrillSpan',
672 0: '', # no need to write out anything for type='continue'
673 1:'\\stopTrillSpan'}.get (self.span_direction, '')
675 class GlissandoEvent (SpanEvent):
676 def ly_expression (self):
678 # TODO: wavy-line glissandos don't work, becasue the style has to be
679 # set before the note, at the \glissando it's already too late!
680 #if self.line_type == 'wavy':
681 #style = "\once\override Glissando #'style = #'zigzag"
682 # In lilypond, glissando is NOT a spanner, unlike MusicXML.
683 return {-1: style + '\\glissando',
684 1:''}.get (self.span_direction, '')
686 class ArpeggioEvent(Event):
687 def wait_for_note (self):
689 def ly_expression (self):
690 return ('\\arpeggio')
693 class TieEvent(Event):
694 def ly_expression (self):
698 class HairpinEvent (SpanEvent):
699 def set_span_type (self, type):
700 self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
701 def hairpin_to_ly (self):
702 if self.span_direction == 1:
705 return {1: '\<', -1: '\>'}.get (self.span_type, '')
707 def ly_expression (self):
708 return self.hairpin_to_ly ()
710 def print_ly (self, printer):
711 val = self.hairpin_to_ly ()
717 class DynamicsEvent (Event):
720 self.available_commands = [ "ppppp", "pppp", "ppp", "pp", "p",
722 "f", "ff", "fff", "ffff",
723 "fp", "sf", "sff", "sp", "spp", "sfz", "rfz" ];
724 def wait_for_note (self):
726 def ly_expression (self):
727 if self.type == None:
729 elif self.type in self.available_commands:
730 return '\%s' % self.type
732 return '-\markup{ \dynamic %s }' % self.type
734 def print_ly (self, printer):
735 if self.type == None:
737 elif self.type in self.available_commands:
738 printer.dump ("\\%s" % self.type)
740 printer.dump ("-\\markup{ \\dynamic %s }" % self.type)
743 class TextEvent (Event):
746 self.force_direction = None
748 def wait_for_note (self):
751 def direction_mod (self):
752 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
754 def ly_expression (self):
755 base_string = '%s\"%s\"'
757 base_string = '%s\markup{ ' + self.markup + ' {%s} }'
758 return base_string % (self.direction_mod (), self.text)
760 class ArticulationEvent (Event):
763 self.force_direction = None
764 def wait_for_note (self):
767 def direction_mod (self):
768 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '')
770 def ly_expression (self):
771 return '%s\\%s' % (self.direction_mod (), self.type)
773 class ShortArticulationEvent (ArticulationEvent):
774 def direction_mod (self):
776 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
777 def ly_expression (self):
778 return '%s%s' % (self.direction_mod (), self.type)
780 class NoDirectionArticulationEvent (ArticulationEvent):
781 def ly_expression (self):
782 return '\\%s' % self.type
784 class MarkupEvent (ShortArticulationEvent):
786 ArticulationEvent.__init__ (self)
788 def ly_expression (self):
790 return "%s\\markup { %s }" % (self.direction_mod (), self.contents)
794 class FretEvent (MarkupEvent):
796 MarkupEvent.__init__ (self)
797 self.force_direction = 1
802 def ly_expression (self):
804 if self.strings <> 6:
805 val += "w:%s;" % self.strings
807 val += "h:%s;" % self.frets
808 if self.barre and len (self.barre) >= 3:
809 val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2])
810 have_fingering = False
811 for i in self.elements:
813 val += "%s-%s" % (i[0], i[1])
815 have_fingering = True
821 return "%s\\markup { \\fret-diagram #\"%s\" }" % (self.direction_mod (), val)
825 class TremoloEvent (ArticulationEvent):
827 Event.__init__ (self)
830 def ly_expression (self):
832 if self.bars and self.bars > 0:
833 str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
836 class BendEvent (ArticulationEvent):
838 Event.__init__ (self)
840 def ly_expression (self):
842 return "-\\bendAfter #%s" % self.alter
846 class RhythmicEvent(Event):
848 Event.__init__ (self)
849 self.duration = Duration()
851 def get_length (self):
852 return self.duration.get_length()
854 def get_properties (self):
855 return ("'duration %s"
856 % self.duration.lisp_expression ())
858 class RestEvent (RhythmicEvent):
860 RhythmicEvent.__init__ (self)
862 def ly_expression (self):
864 return "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
866 return 'r%s' % self.duration.ly_expression ()
868 def print_ly (self, printer):
870 self.pitch.print_ly (printer)
871 self.duration.print_ly (printer)
875 self.duration.print_ly (printer)
877 class SkipEvent (RhythmicEvent):
878 def ly_expression (self):
879 return 's%s' % self.duration.ly_expression ()
881 class NoteEvent(RhythmicEvent):
883 RhythmicEvent.__init__ (self)
885 self.drum_type = None
886 self.cautionary = False
887 self.forced_accidental = False
889 def get_properties (self):
890 str = RhythmicEvent.get_properties (self)
893 str += self.pitch.lisp_expression ()
895 str += "'drum-type '%s" % self.drum_type
899 def pitch_mods (self):
903 if self.forced_accidental:
908 def ly_expression (self):
910 return '%s%s%s' % (self.pitch.ly_expression (),
912 self.duration.ly_expression ())
914 return '%s%s' (self.drum_type,
915 self.duration.ly_expression ())
917 def print_ly (self, printer):
919 self.pitch.print_ly (printer)
920 printer (self.pitch_mods ())
922 printer (self.drum_type)
924 self.duration.print_ly (printer)
926 class KeySignatureChange (Music):
928 Music.__init__ (self)
933 def ly_expression (self):
934 return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
937 def lisp_expression (self):
938 pairs = ['(%d . %d)' % (i , self.scale[i]) for i in range (0,7)]
939 scale_str = ("'(%s)" % string.join (pairs))
941 return """ (make-music 'KeyChangeEvent
942 'pitch-alist %s) """ % scale_str
944 class TimeSignatureChange (Music):
946 Music.__init__ (self)
947 self.fraction = (4,4)
948 def ly_expression (self):
949 return '\\time %d/%d ' % self.fraction
951 class ClefChange (Music):
953 Music.__init__ (self)
958 def octave_modifier (self):
959 return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
960 def clef_name (self):
961 return {('G', 2): "treble",
964 ('C', 2): "mezzosoprano",
967 ('C', 5): "baritone",
968 ('F', 3): "varbaritone",
971 ("percussion", 2): "percussion",
972 ("TAB", 5): "tab"}.get ((self.type, self.position), None)
973 def ly_expression (self):
974 return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
977 "G": ("clefs.G", -2, -6),
978 "C": ("clefs.C", 0, 0),
979 "F": ("clefs.F", 2, 6),
982 def lisp_expression (self):
984 (glyph, pos, c0) = self.clef_dict[self.type]
988 (make-music 'SequentialMusic
991 (make-property-set 'clefGlyph "%s") 'Staff)
993 (make-property-set 'clefPosition %d) 'Staff)
995 (make-property-set 'middleCPosition %d) 'Staff)))
996 """ % (glyph, pos, c0)
1000 class StaffChange (Music):
1001 def __init__ (self, staff):
1002 Music.__init__ (self)
1004 def ly_expression (self):
1006 return "\\change Staff=\"%s\"" % self.staff
1011 class MultiMeasureRest(Music):
1013 def lisp_expression (self):
1016 'MultiMeasureRestMusicGroup
1018 (list (make-music (quote BarCheck))
1023 'MultiMeasureRestEvent
1026 (make-music (quote BarCheck))))
1027 """ % self.duration.lisp_expression ()
1029 def ly_expression (self):
1030 return 'R%s' % self.duration.ly_expression ()
1034 def __init__ (self, command = "StaffGroup"):
1035 self.stafftype = command
1037 self.instrument_name = None
1038 self.short_instrument_name = None
1042 # part_information is a list with entries of the form
1043 # [staffid, voicelist]
1044 # where voicelist is a list with entries of the form
1045 # [voiceid1, [lyricsid11, lyricsid12,...] ]
1046 self.part_information = None
1048 def appendStaff (self, staff):
1049 self.children.append (staff)
1051 def setPartInformation (self, part_name, staves_info):
1052 if part_name == self.id:
1053 self.part_information = staves_info
1055 for c in self.children:
1056 c.setPartInformation (part_name, staves_info)
1058 def print_ly_contents (self, printer):
1059 for c in self.children:
1061 c.print_ly (printer)
1062 def print_ly_overrides (self, printer):
1064 needs_with |= self.spanbar == "no"
1065 needs_with |= self.instrument_name != None
1066 needs_with |= self.short_instrument_name != None
1067 needs_with |= (self.symbol != None) and (self.symbol != "bracket")
1069 printer.dump ("\\with {")
1070 if self.instrument_name or self.short_instrument_name:
1071 printer.dump ("\\consists \"Instrument_name_engraver\"")
1072 if self.spanbar == "no":
1073 printer.dump ("\\override SpanBar #'transparent = ##t")
1074 brack = {"brace": "SystemStartBrace",
1076 "line": "SystemStartBar"}.get (self.symbol, None)
1078 printer.dump ("systemStartDelimiter = #'%s" % brack)
1081 def print_ly (self, printer):
1083 printer.dump ("\\new %s" % self.stafftype)
1084 self.print_ly_overrides (printer)
1087 if self.stafftype and self.instrument_name:
1088 printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
1089 escape_instrument_string (self.instrument_name)))
1091 if self.stafftype and self.short_instrument_name:
1092 printer.dump ("\\set %s.shortInstrumentName = %s\n" % (self.stafftype,
1093 escape_instrument_string (self.short_instrument_name)))
1095 self.print_ly_contents (printer)
1101 class Staff (StaffGroup):
1102 def __init__ (self):
1103 StaffGroup.__init__ (self, "Staff")
1106 def print_ly_overrides (self, printer):
1109 def print_ly_contents (self, printer):
1110 if not self.id or not self.part_information:
1113 for [staff_id, voices] in self.part_information:
1115 printer ('\\context Staff = "%s" << ' % staff_id)
1117 printer ('\\context Staff << ')
1120 nr_voices = len (voices)
1121 for [v, lyrics] in voices:
1123 voice_count_text = ''
1125 voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo',
1126 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
1127 printer ('\\context Voice = "%s" {%s \\%s }' % (v,voice_count_text,v))
1131 printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
1135 def print_ly (self, printer):
1136 if self.part_information and len (self.part_information) > 1:
1137 self.stafftype = "PianoStaff"
1138 StaffGroup.print_ly (self, printer)
1143 bflat.alteration = -1
1153 print bflat.semitones()
1154 print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
1155 print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
1157 print bflat.semitones(), 'down'
1158 print bflat.transposed (down)
1159 print bflat.transposed (down).transposed (down)
1160 print bflat.transposed (down).transposed (down).transposed (down)
1164 def test_printer ():
1172 m = SequentialMusic()
1173 m.append (make_note ())
1174 m.append (make_note ())
1175 m.append (make_note ())
1178 t = TimeScaledMusic ()
1184 m = SequentialMusic ()
1185 m.append (make_tup ())
1186 m.append (make_tup ())
1187 m.append (make_tup ())
1189 printer = Output_printer()
1190 m.print_ly (printer)
1194 m = SequentialMusic()
1198 n.duration.duration_log = l
1200 evc.insert_around (None, n, 0)
1201 m.insert_around (None, evc, 0)
1205 n.duration.duration_log = l
1207 evc.insert_around (None, n, 0)
1208 m.insert_around (None, evc, 0)
1212 n.duration.duration_log = l
1214 evc.insert_around (None, n, 0)
1215 m.insert_around (None, evc, 0)
1219 m.insert_around (None, evc, 0)
1224 tonic.alteration = -2
1225 n = KeySignatureChange()
1226 n.tonic=tonic.copy()
1227 n.scale = [0, 0, -2, 0, 0,-2,-2]
1229 evc.insert_around (None, n, 0)
1230 m.insert_around (None, evc, 0)
1235 if __name__ == '__main__':
1241 expr.set_start (Rational (0))
1242 print expr.ly_expression()
1243 start = Rational (0,4)
1244 stop = Rational (4,2)
1245 def sub(x, start=start, stop=stop):
1246 ok = x.start >= start and x.start +x.get_length() <= stop
1249 print expr.lisp_sub_expression(sub)