1 # -*- coding: utf-8 -*-
10 from rational import Rational
12 # Store previously converted pitch for \relative conversion as a global state variable
14 relative_pitches = False
17 ly.stderr_write ((_ ("warning: %s") % str) + "\n")
20 def escape_instrument_string (input_string):
21 retstring = string.replace (input_string, "\"", "\\\"")
22 if re.match ('.*[\r\n]+.*', retstring):
23 rx = re.compile (r'[\n\r]+')
24 strings = rx.split (retstring)
25 retstring = "\\markup { \\column { "
27 retstring += "\\line {\"" + s + "\"} "
30 retstring = "\"" + retstring + "\""
33 class Output_stack_element:
35 self.factor = Rational (1)
37 o = Output_stack_element()
38 o.factor = self.factor
43 """A class that takes care of formatting (eg.: indenting) a
44 Music expression as a .ly file.
52 self._file = sys.stdout
54 self._output_state_stack = [Output_stack_element()]
55 self._skipspace = False
56 self._last_duration = None
58 def set_file (self, file):
61 def dump_version (self):
63 self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
66 def get_indent (self):
67 return self._nesting * self._indent
70 last = self._output_state_stack[-1]
71 self._output_state_stack.append (last.copy())
73 def add_factor (self, factor):
75 self._output_state_stack[-1].factor *= factor
78 del self._output_state_stack[-1]
79 if not self._output_state_stack:
82 def duration_factor (self):
83 return self._output_state_stack[-1].factor
85 def print_verbatim (self, str):
88 def unformatted_output (self, str):
89 # don't indent on \< and indent only once on <<
90 self._nesting += ( str.count ('<')
91 - str.count ('\<') - str.count ('<<')
93 self._nesting -= ( str.count ('>') - str.count ('\>') - str.count ('>>')
94 - str.count ('->') - str.count ('_>')
97 self.print_verbatim (str)
99 def print_duration_string (self, str):
100 if self._last_duration == str:
103 self.unformatted_output (str)
105 def add_word (self, str):
106 if (len (str) + 1 + len (self._line) > self._line_len):
108 self._skipspace = True
110 if not self._skipspace:
112 self.unformatted_output (str)
113 self._skipspace = False
116 self._file.write (self._line + '\n')
117 self._line = ' ' * self._indent * self._nesting
118 self._skipspace = True
120 def skipspace (self):
121 self._skipspace = True
123 def __call__(self, arg):
126 def dump (self, str):
128 self._skipspace = False
129 self.unformatted_output (str)
131 words = string.split (str)
144 self.duration_log = 0
146 self.factor = Rational (1)
148 def lisp_expression (self):
149 return '(ly:make-duration %d %d %d %d)' % (self.duration_log,
151 self.factor.numerator (),
152 self.factor.denominator ())
155 def ly_expression (self, factor = None, scheme_mode = False):
159 if self.duration_log < 0:
161 longer_dict = {-1: "breve", -2: "longa"}
163 longer_dict = {-1: "\\breve", -2: "\\longa"}
164 str = longer_dict.get (self.duration_log, "1")
166 str = '%d' % (1 << self.duration_log)
169 if factor <> Rational (1,1):
170 if factor.denominator () <> 1:
171 str += '*%d/%d' % (factor.numerator (), factor.denominator ())
173 str += '*%d' % factor.numerator ()
177 def print_ly (self, outputter):
178 str = self.ly_expression (self.factor / outputter.duration_factor ())
179 outputter.print_duration_string (str)
182 return self.ly_expression()
187 d.duration_log = self.duration_log
188 d.factor = self.factor
191 def get_length (self):
192 dot_fact = Rational( (1 << (1 + self.dots))-1,
195 log = abs (self.duration_log)
197 if self.duration_log < 0:
198 base = Rational (dur)
200 base = Rational (1, dur)
202 return base * dot_fact * self.factor
205 # Implement the different note names for the various languages
206 def pitch_generic (pitch, notenames, accidentals):
207 str = notenames[pitch.step]
208 halftones = int (pitch.alteration)
210 str += accidentals[0] * (-halftones)
211 elif pitch.alteration > 0:
212 str += accidentals[3] * (halftones)
213 # Handle remaining fraction to pitch.alteration (for microtones)
214 if (halftones != pitch.alteration):
215 if None in accidentals[1:3]:
216 warning (_ ("Language does not support microtones contained in the piece"))
219 str += {-0.5: accidentals[1], 0.5: accidentals[2]}[pitch.alteration-halftones]
221 warning (_ ("Language does not support microtones contained in the piece"))
224 def pitch_general (pitch):
225 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['es', 'eh', 'ih', 'is'])
226 return str.replace ('aes', 'as').replace ('ees', 'es')
228 def pitch_nederlands (pitch):
229 return pitch_general (pitch)
231 def pitch_english (pitch):
232 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['f', 'qf', 'qs', 's'])
233 return str.replace ('aes', 'as').replace ('ees', 'es')
235 def pitch_deutsch (pitch):
236 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['es', 'eh', 'ih', 'is'])
237 return str.replace ('hes', 'b').replace ('aes', 'as').replace ('ees', 'es')
239 def pitch_norsk (pitch):
240 return pitch_deutsch (pitch)
242 def pitch_svenska (pitch):
243 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['ess', None, None, 'iss'])
244 return str.replace ('hess', 'b').replace ('aes', 'as').replace ('ees', 'es')
246 def pitch_italiano (pitch):
247 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', 'sb', 'sd', 'd'])
250 def pitch_catalan (pitch):
251 return pitch_italiano (pitch)
253 def pitch_espanol (pitch):
254 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 's'])
257 def pitch_vlaams (pitch):
258 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 'k'])
261 def set_pitch_language (language):
262 global pitch_generating_function
264 "nederlands": pitch_nederlands,
265 "english": pitch_english,
266 "deutsch": pitch_deutsch,
267 "norsk": pitch_norsk,
268 "svenska": pitch_svenska,
269 "italiano": pitch_italiano,
270 "catalan": pitch_catalan,
271 "espanol": pitch_espanol,
272 "vlaams": pitch_vlaams}
273 pitch_generating_function = function_dict.get (language, pitch_general)
275 # global variable to hold the formatting function.
276 pitch_generating_function = pitch_general
284 self._force_absolute_pitch = False
287 return self.ly_expression()
289 def transposed (self, interval):
291 c.alteration += interval.alteration
292 c.step += interval.step
293 c.octave += interval.octave
296 target_st = self.semitones() + interval.semitones()
297 c.alteration += target_st - c.semitones()
304 c.octave += c.step / 7
307 def lisp_expression (self):
308 return '(ly:make-pitch %d %d %d)' % (self.octave,
314 p.alteration = self.alteration
316 p.octave = self.octave
320 return self.step + self.octave *7
322 def semitones (self):
323 return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
325 def ly_step_expression (self):
326 return pitch_generating_function (self)
328 def absolute_pitch (self):
330 return "'" * (self.octave + 1)
331 elif self.octave < -1:
332 return "," * (-self.octave - 1)
336 def relative_pitch (self):
337 global previous_pitch
338 if not previous_pitch:
339 previous_pitch = self
340 return self.absolute_pitch ()
341 previous_pitch_steps = previous_pitch.octave * 7 + previous_pitch.step
342 this_pitch_steps = self.octave * 7 + self.step
343 pitch_diff = (this_pitch_steps - previous_pitch_steps)
344 previous_pitch = self
346 return "'" * ((pitch_diff + 3) / 7)
347 elif pitch_diff < -3:
348 return "," * ((-pitch_diff + 3) / 7)
352 def ly_expression (self):
353 str = self.ly_step_expression ()
354 if relative_pitches and not self._force_absolute_pitch:
355 str += self.relative_pitch ()
357 str += self.absolute_pitch ()
361 def print_ly (self, outputter):
362 outputter (self.ly_expression())
367 self.start = Rational (0)
369 self.identifier = None
371 def get_length(self):
374 def get_properties (self):
377 def has_children (self):
380 def get_index (self):
382 return self.parent.elements.index (self)
386 return self.__class__.__name__
388 def lisp_expression (self):
391 props = self.get_properties ()
393 return "(make-music '%s %s)" % (name, props)
395 def set_start (self, start):
398 def find_first (self, predicate):
403 def print_comment (self, printer, text = None):
414 lines = string.split (text, '\n')
417 printer.unformatted_output ('% ' + l)
421 def print_with_identifier (self, printer):
423 printer ("\\%s" % self.identifier)
425 self.print_ly (printer)
427 def print_ly (self, printer):
428 printer (self.ly_expression ())
430 class MusicWrapper (Music):
434 def print_ly (self, func):
435 self.element.print_ly (func)
437 class ModeChangingMusicWrapper (MusicWrapper):
439 MusicWrapper.__init__ (self)
440 self.mode = 'notemode'
442 def print_ly (self, func):
443 func ('\\%s' % self.mode)
444 MusicWrapper.print_ly (self, func)
446 class RelativeMusic (MusicWrapper):
448 MusicWrapper.__init__ (self)
449 self.basepitch = None
451 def print_ly (self, func):
452 global previous_pitch
453 global relative_pitches
454 prev_relative_pitches = relative_pitches
455 relative_pitches = True
456 previous_pitch = self.basepitch
457 if not previous_pitch:
458 previous_pitch = Pitch ()
459 func ('\\relative %s%s' % (pitch_generating_function (previous_pitch),
460 previous_pitch.absolute_pitch ()))
461 MusicWrapper.print_ly (self, func)
462 relative_pitches = prev_relative_pitches
464 class TimeScaledMusic (MusicWrapper):
466 MusicWrapper.__init__ (self)
469 self.display_number = "actual" # valid values "actual" | "both" | None
470 # Display the basic note length for the tuplet:
471 self.display_type = None # value values "actual" | "both" | None
472 self.display_bracket = "bracket" # valid values "bracket" | "curved" | None
473 self.actual_type = None # The actually played unit of the scaling
474 self.normal_type = None # The basic unit of the scaling
475 self.display_numerator = None
476 self.display_denominator = None
478 def print_ly (self, func):
479 if self.display_bracket == None:
480 func ("\\once \\override TupletBracket #'stencil = ##f")
482 elif self.display_bracket == "curved":
483 warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
484 func ("\\once \\override TupletBracket #'stencil = #ly:slur::print")
487 base_number_function = {None: "#f",
488 "actual": "tuplet-number::calc-denominator-text",
489 "both": "tuplet-number::calc-fraction-text"}.get (self.display_number, None)
490 # If we have non-standard numerator/denominator, use our custom function
491 if self.display_number == "actual" and self.display_denominator:
492 base_number_function = "(tuplet-number::non-default-tuplet-denominator-text %s)" % self.display_denominator
493 elif self.display_number == "both" and (self.display_denominator or self.display_numerator):
494 if self.display_numerator:
495 num = self.display_numerator
498 if self.display_denominator:
499 den = self.display_denominator
502 base_number_function = "(tuplet-number::non-default-tuplet-fraction-text %s %s)" % (den, num)
505 if self.display_type == "actual" and self.normal_type:
506 # Obtain the note duration in scheme-mode, i.e. \longa as \\longa
507 base_duration = self.normal_type.ly_expression (None, True)
508 func ("\\once \\override TupletNumber #'text = #(tuplet-number::append-note-wrapper %s \"%s\")" %
509 (base_number_function, base_duration))
511 elif self.display_type == "both": # TODO: Implement this using actual_type and normal_type!
512 if self.display_number == None:
513 func ("\\once \\override TupletNumber #'stencil = ##f")
515 elif self.display_number == "both":
516 den_duration = self.normal_type.ly_expression (None, True)
517 # If we don't have an actual type set, use the normal duration!
519 num_duration = self.actual_type.ly_expression (None, True)
521 num_duration = den_duration
522 if (self.display_denominator or self.display_numerator):
523 func ("\\once \\override TupletNumber #'text = #(tuplet-number::non-default-fraction-with-notes %s \"%s\" %s \"%s\")" %
524 (self.display_denominator, den_duration,
525 self.display_numerator, num_duration))
528 func ("\\once \\override TupletNumber #'text = #(tuplet-number::fraction-with-notes \"%s\" \"%s\")" %
529 (den_duration, num_duration))
532 if self.display_number == None:
533 func ("\\once \\override TupletNumber #'stencil = ##f")
535 elif self.display_number == "both":
536 func ("\\once \\override TupletNumber #'text = #%s" % base_number_function)
539 func ('\\times %d/%d ' %
540 (self.numerator, self.denominator))
541 func.add_factor (Rational (self.numerator, self.denominator))
542 MusicWrapper.print_ly (self, func)
545 class NestedMusic(Music):
547 Music.__init__ (self)
550 def append (self, what):
552 self.elements.append (what)
554 def has_children (self):
557 def insert_around (self, succ, elt, dir):
558 assert elt.parent == None
559 assert succ == None or succ in self.elements
564 idx = self.elements.index (succ)
571 idx = len (self.elements)
573 self.elements.insert (idx, elt)
576 def get_properties (self):
577 return ("'elements (list %s)"
578 % string.join (map (lambda x: x.lisp_expression(),
581 def get_subset_properties (self, predicate):
582 return ("'elements (list %s)"
583 % string.join (map (lambda x: x.lisp_expression(),
584 filter ( predicate, self.elements))))
585 def get_neighbor (self, music, dir):
586 assert music.parent == self
587 idx = self.elements.index (music)
589 idx = min (idx, len (self.elements) -1)
592 return self.elements[idx]
594 def delete_element (self, element):
595 assert element in self.elements
597 self.elements.remove (element)
598 element.parent = None
600 def set_start (self, start):
602 for e in self.elements:
605 def find_first (self, predicate):
606 r = Music.find_first (self, predicate)
610 for e in self.elements:
611 r = e.find_first (predicate)
616 class SequentialMusic (NestedMusic):
617 def get_last_event_chord (self):
619 at = len( self.elements ) - 1
621 not isinstance (self.elements[at], ChordEvent) and
622 not isinstance (self.elements[at], BarLine)):
625 if (at >= 0 and isinstance (self.elements[at], ChordEvent)):
626 value = self.elements[at]
629 def print_ly (self, printer, newline = True):
632 self.print_comment (printer)
636 for e in self.elements:
643 def lisp_sub_expression (self, pred):
647 props = self.get_subset_properties (pred)
649 return "(make-music '%s %s)" % (name, props)
651 def set_start (self, start):
652 for e in self.elements:
654 start += e.get_length()
658 self.repeat_type = "volta"
659 self.repeat_count = 2
662 def set_music (self, music):
663 if isinstance (music, Music):
665 elif isinstance (music, list):
666 self.music = SequentialMusic ()
667 self.music.elements = music
669 warning (_ ("unable to set the music %(music)s for the repeat %(repeat)s") % \
670 {'music':music, 'repeat':self})
671 def add_ending (self, music):
672 self.endings.append (music)
673 def print_ly (self, printer):
674 printer.dump ('\\repeat %s %s' % (self.repeat_type, self.repeat_count))
676 self.music.print_ly (printer)
678 warning (_ ("encountered repeat without body"))
681 printer.dump ('\\alternative {')
682 for e in self.endings:
689 self.lyrics_syllables = []
691 def print_ly (self, printer):
692 printer.dump ("\lyricmode {")
693 for l in self.lyrics_syllables:
694 printer.dump ( "%s " % l )
697 def ly_expression (self):
698 lstr = "\lyricmode {\n "
699 for l in self.lyrics_syllables:
707 self.header_fields = {}
708 def set_field (self, field, value):
709 self.header_fields[field] = value
711 def print_ly (self, printer):
712 printer.dump ("\header {")
714 for (k,v) in self.header_fields.items ():
716 printer.dump ('%s = %s' % (k,v))
725 self.global_staff_size = -1
728 self.page_height = -1
731 self.bottom_margin = -1
732 self.left_margin = -1
733 self.right_margin = -1
734 self.system_left_margin = -1
735 self.system_right_margin = -1
736 self.system_distance = -1
737 self.top_system_distance = -1
739 def print_length_field (self, printer, field, value):
741 printer.dump ("%s = %s\\cm" % (field, value))
743 def print_ly (self, printer):
744 if self.global_staff_size > 0:
745 printer.dump ('#(set-global-staff-size %s)' % self.global_staff_size)
747 printer.dump ('\\paper {')
749 self.print_length_field (printer, "paper-width", self.page_width)
750 self.print_length_field (printer, "paper-height", self.page_height)
751 self.print_length_field (printer, "top-margin", self.top_margin)
752 self.print_length_field (printer, "botton-margin", self.bottom_margin)
753 self.print_length_field (printer, "left-margin", self.left_margin)
754 # TODO: maybe set line-width instead of right-margin?
755 self.print_length_field (printer, "right-margin", self.right_margin)
756 # TODO: What's the corresponding setting for system_left_margin and
757 # system_right_margin in LilyPond?
758 self.print_length_field (printer, "between-system-space", self.system_distance)
759 self.print_length_field (printer, "page-top-space", self.top_system_distance)
766 self.context_dict = {}
767 def add_context (self, context):
768 if not self.context_dict.has_key (context):
769 self.context_dict[context] = []
770 def set_context_item (self, context, item):
771 self.add_context (context)
772 if not item in self.context_dict[context]:
773 self.context_dict[context].append (item)
774 def print_ly (self, printer):
775 if self.context_dict.items ():
776 printer.dump ('\\layout {')
778 for (context, defs) in self.context_dict.items ():
779 printer.dump ('\\context { \\%s' % context)
790 class ChordEvent (NestedMusic):
792 NestedMusic.__init__ (self)
793 self.after_grace_elements = None
794 self.grace_elements = None
795 self.grace_type = None
796 def append_grace (self, element):
798 if not self.grace_elements:
799 self.grace_elements = SequentialMusic ()
800 self.grace_elements.append (element)
801 def append_after_grace (self, element):
803 if not self.after_grace_elements:
804 self.after_grace_elements = SequentialMusic ()
805 self.after_grace_elements.append (element)
807 def has_elements (self):
808 return [e for e in self.elements if
809 isinstance (e, NoteEvent) or isinstance (e, RestEvent)] != []
812 def get_length (self):
814 for e in self.elements:
815 l = max(l, e.get_length())
818 def get_duration (self):
819 note_events = [e for e in self.elements if
820 isinstance (e, NoteEvent) or isinstance (e, RestEvent)]
822 return note_events[0].duration
826 def print_ly (self, printer):
827 note_events = [e for e in self.elements if
828 isinstance (e, NoteEvent)]
830 rest_events = [e for e in self.elements if
831 isinstance (e, RhythmicEvent)
832 and not isinstance (e, NoteEvent)]
834 other_events = [e for e in self.elements if
835 not isinstance (e, RhythmicEvent)]
837 if self.after_grace_elements:
838 printer ('\\afterGrace {')
840 if self.grace_elements and self.elements:
842 printer ('\\%s' % self.grace_type)
845 # don't print newlines after the { and } braces
846 self.grace_elements.print_ly (printer, False)
847 elif self.grace_elements: # no self.elements!
848 warning (_ ("Grace note with no following music: %s") % self.grace_elements)
850 printer ('\\%s' % self.grace_type)
853 self.grace_elements.print_ly (printer, False)
856 # Print all overrides and other settings needed by the
857 # articulations/ornaments before the note
858 for e in other_events:
859 e.print_before_note (printer)
862 rest_events[0].print_ly (printer)
863 elif len (note_events) == 1:
864 note_events[0].print_ly (printer)
866 global previous_pitch
869 for x in note_events:
870 pitches.append (x.chord_element_ly ())
872 basepitch = previous_pitch
873 printer ('<%s>' % string.join (pitches))
874 previous_pitch = basepitch
875 duration = self.get_duration ()
877 duration.print_ly (printer)
881 for e in other_events:
884 for e in other_events:
885 e.print_after_note (printer)
887 if self.after_grace_elements:
889 self.after_grace_elements.print_ly (printer, False)
891 self.print_comment (printer)
893 class Partial (Music):
895 Music.__init__ (self)
897 def print_ly (self, printer):
899 printer.dump ("\\partial %s" % self.partial.ly_expression ())
901 class BarLine (Music):
903 Music.__init__ (self)
907 def print_ly (self, printer):
908 bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': "dashed",
909 'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
910 'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'",
911 'short': "'", 'none': "" }.get (self.type, None)
912 if bar_symbol <> None:
913 printer.dump ('\\bar "%s"' % bar_symbol)
917 if self.bar_number > 0 and (self.bar_number % 10) == 0:
918 printer.dump ("\\barNumberCheck #%d " % self.bar_number)
919 elif self.bar_number > 0:
920 printer.print_verbatim (' %% %d' % self.bar_number)
923 def ly_expression (self):
928 # strings to print before the note to which an event is attached.
929 # Ignored for notes etc.
930 self.before_note = None
931 self.after_note = None
932 # print something before the note to which an event is attached, e.g. overrides
933 def print_before_note (self, printer):
935 printer.dump (self.before_note)
936 # print something after the note to which an event is attached, e.g. resetting
937 def print_after_note (self, printer):
939 printer.dump (self.after_note)
942 class SpanEvent (Event):
944 Event.__init__ (self)
945 self.span_direction = 0 # start/stop
946 self.line_type = 'solid'
947 self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
948 self.size = 0 # size of e.g. ocrave shift
949 def wait_for_note (self):
951 def get_properties(self):
952 return "'span-direction %d" % self.span_direction
953 def set_span_type (self, type):
954 self.span_type = type
956 class SlurEvent (SpanEvent):
957 def print_before_note (self, printer):
958 command = {'dotted': '\\slurDotted',
959 'dashed' : '\\slurDashed'}.get (self.line_type, '')
960 if command and self.span_direction == -1:
961 printer.dump (command)
962 def print_after_note (self, printer):
963 # reset non-solid slur types!
964 command = {'dotted': '\\slurSolid',
965 'dashed' : '\\slurSolid'}.get (self.line_type, '')
966 if command and self.span_direction == -1:
967 printer.dump (command)
968 def ly_expression (self):
969 return {-1: '(', 1:')'}.get (self.span_direction, '')
971 class BeamEvent (SpanEvent):
972 def ly_expression (self):
973 return {-1: '[', 1:']'}.get (self.span_direction, '')
975 class PedalEvent (SpanEvent):
976 def ly_expression (self):
977 return {-1: '\\sustainOn',
978 0:'\\sustainOff\\sustainOn',
979 1:'\\sustainOff'}.get (self.span_direction, '')
981 class TextSpannerEvent (SpanEvent):
982 def ly_expression (self):
983 return {-1: '\\startTextSpan',
984 1:'\\stopTextSpan'}.get (self.span_direction, '')
986 class BracketSpannerEvent (SpanEvent):
987 # Ligature brackets use prefix-notation!!!
988 def print_before_note (self, printer):
989 if self.span_direction == -1:
991 # the bracket after the last note
992 def print_after_note (self, printer):
993 if self.span_direction == 1:
995 # we're printing everything in print_(before|after)_note...
996 def ly_expression (self):
1000 class OctaveShiftEvent (SpanEvent):
1001 def wait_for_note (self):
1003 def set_span_type (self, type):
1004 self.span_type = {'up': 1, 'down': -1}.get (type, 0)
1005 def ly_octave_shift_indicator (self):
1006 # convert 8/15 to lilypond indicators (+-1/+-2)
1008 value = {8: 1, 15: 2}[self.size]
1010 warning (_ ("Invalid octave shift size found: %s. Using no shift.") % self.size)
1012 # negative values go up!
1013 value *= -1*self.span_type
1015 def ly_expression (self):
1016 dir = self.ly_octave_shift_indicator ()
1019 value = '\ottava #%s' % dir
1022 1: '\ottava #0'}.get (self.span_direction, '')
1024 class TrillSpanEvent (SpanEvent):
1025 def ly_expression (self):
1026 return {-1: '\\startTrillSpan',
1027 0: '', # no need to write out anything for type='continue'
1028 1:'\\stopTrillSpan'}.get (self.span_direction, '')
1030 class GlissandoEvent (SpanEvent):
1031 def print_before_note (self, printer):
1032 if self.span_direction == -1:
1034 "dashed" : "dashed-line",
1035 "dotted" : "dotted-line",
1037 }. get (self.line_type, None)
1039 printer.dump ("\\once \\override Glissando #'style = #'%s" % style)
1040 def ly_expression (self):
1041 return {-1: '\\glissando',
1042 1:''}.get (self.span_direction, '')
1044 class ArpeggioEvent(Event):
1045 def __init__ (self):
1046 Event.__init__ (self)
1048 self.non_arpeggiate = False
1049 def wait_for_note (self):
1051 def print_before_note (self, printer):
1052 if self.non_arpeggiate:
1053 printer.dump ("\\arpeggioBracket")
1055 dir = { -1: "\\arpeggioArrowDown", 1: "\\arpeggioArrowUp" }.get (self.direction, '')
1058 def print_after_note (self, printer):
1059 if self.non_arpeggiate or self.direction:
1060 printer.dump ("\\arpeggioNormal")
1061 def ly_expression (self):
1062 return ('\\arpeggio')
1065 class TieEvent(Event):
1066 def ly_expression (self):
1070 class HairpinEvent (SpanEvent):
1071 def set_span_type (self, type):
1072 self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
1073 def hairpin_to_ly (self):
1074 if self.span_direction == 1:
1077 return {1: '\<', -1: '\>'}.get (self.span_type, '')
1079 def ly_expression (self):
1080 return self.hairpin_to_ly ()
1082 def print_ly (self, printer):
1083 val = self.hairpin_to_ly ()
1089 class DynamicsEvent (Event):
1090 def __init__ (self):
1091 Event.__init__ (self)
1093 def wait_for_note (self):
1095 def ly_expression (self):
1097 return '\%s' % self.type
1101 def print_ly (self, printer):
1103 printer.dump ("\\%s" % self.type)
1105 class MarkEvent (Event):
1106 def __init__ (self, text="\\default"):
1107 Event.__init__ (self)
1109 def wait_for_note (self):
1111 def ly_contents (self):
1113 return '%s' % self.mark
1116 def ly_expression (self):
1117 return '\\mark %s' % self.ly_contents ()
1119 class MusicGlyphMarkEvent (MarkEvent):
1120 def ly_contents (self):
1122 return '\\markup { \\musicglyph #"scripts.%s" }' % self.mark
1127 class TextEvent (Event):
1128 def __init__ (self):
1129 Event.__init__ (self)
1131 self.force_direction = None
1133 def wait_for_note (self):
1136 def direction_mod (self):
1137 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
1139 def ly_expression (self):
1140 base_string = '%s\"%s\"'
1142 base_string = '%s\markup{ ' + self.markup + ' {%s} }'
1143 return base_string % (self.direction_mod (), self.text)
1145 class ArticulationEvent (Event):
1146 def __init__ (self):
1147 Event.__init__ (self)
1149 self.force_direction = None
1150 def wait_for_note (self):
1153 def direction_mod (self):
1154 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '')
1156 def ly_expression (self):
1157 return '%s\\%s' % (self.direction_mod (), self.type)
1159 class ShortArticulationEvent (ArticulationEvent):
1160 def direction_mod (self):
1162 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
1163 def ly_expression (self):
1165 return '%s%s' % (self.direction_mod (), self.type)
1169 class NoDirectionArticulationEvent (ArticulationEvent):
1170 def ly_expression (self):
1172 return '\\%s' % self.type
1176 class MarkupEvent (ShortArticulationEvent):
1177 def __init__ (self):
1178 ArticulationEvent.__init__ (self)
1179 self.contents = None
1180 def ly_expression (self):
1182 return "%s\\markup { %s }" % (self.direction_mod (), self.contents)
1186 class FretEvent (MarkupEvent):
1187 def __init__ (self):
1188 MarkupEvent.__init__ (self)
1189 self.force_direction = 1
1194 def ly_expression (self):
1196 if self.strings <> 6:
1197 val += "w:%s;" % self.strings
1199 val += "h:%s;" % self.frets
1200 if self.barre and len (self.barre) >= 3:
1201 val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2])
1202 have_fingering = False
1203 for i in self.elements:
1205 val += "%s-%s" % (i[0], i[1])
1207 have_fingering = True
1213 return "%s\\markup { \\fret-diagram #\"%s\" }" % (self.direction_mod (), val)
1218 class FunctionWrapperEvent (Event):
1219 def __init__ (self, function_name = None):
1220 Event.__init__ (self)
1221 self.function_name = function_name
1222 def pre_note_ly (self, is_chord_element):
1223 if self.function_name:
1224 return "\\%s" % self.function_name
1227 def pre_chord_ly (self):
1229 def ly_expression (self):
1230 if self.function_name:
1231 return "\\%s" % self.function_name
1235 class ParenthesizeEvent (FunctionWrapperEvent):
1236 def __init__ (self):
1237 FunctionWrapperEvent.__init__ (self, "parenthesize")
1239 class NotestyleEvent (Event):
1240 def __init__ (self):
1241 Event.__init__ (self)
1244 def pre_chord_ly (self):
1246 return "\\once \\override NoteHead #'style = #%s" % self.style
1249 def pre_note_ly (self, is_chord_element):
1250 if self.style and is_chord_element:
1251 return "\\tweak #'style #%s" % self.style
1254 def ly_expression (self):
1255 return self.pre_chord_ly ()
1259 def __init__ (self):
1263 return self.ly_expression()
1264 def ly_expression (self):
1265 return pitch_generating_function (self)
1267 class ChordModification:
1268 def __init__ (self):
1272 def ly_expression (self):
1274 val = {1: ".", -1: "^" }.get (self.type, "")
1275 val += "%s" % self.step
1276 val += {1: "+", -1: "-"}.get (self.alteration, "")
1281 class ChordNameEvent (Event):
1282 def __init__ (self):
1283 Event.__init__ (self)
1286 self.duration = None
1287 self.modifications = []
1289 def add_modification (self, mod):
1290 self.modifications.append (mod)
1291 def ly_expression (self):
1294 value = self.root.ly_expression ()
1296 value += self.duration.ly_expression ()
1300 # First print all additions/changes, and only afterwards all subtractions
1301 for m in self.modifications:
1303 value += m.ly_expression ()
1304 for m in self.modifications:
1306 value += m.ly_expression ()
1308 value += "/+%s" % self.bass.ly_expression ()
1312 class TremoloEvent (ArticulationEvent):
1313 def __init__ (self):
1314 Event.__init__ (self)
1317 def ly_expression (self):
1319 if self.bars and self.bars > 0:
1320 str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
1323 class BendEvent (ArticulationEvent):
1324 def __init__ (self):
1325 Event.__init__ (self)
1327 def ly_expression (self):
1328 if self.alter != None:
1329 return "-\\bendAfter #%s" % self.alter
1333 class RhythmicEvent(Event):
1334 def __init__ (self):
1335 Event.__init__ (self)
1336 self.duration = Duration()
1337 self.associated_events = []
1339 def add_associated_event (self, ev):
1341 self.associated_events.append (ev)
1343 def pre_chord_ly (self):
1344 return [ev.pre_chord_ly () for ev in self.associated_events]
1346 def pre_note_ly (self, is_chord_element):
1347 return [ev.pre_note_ly (is_chord_element) for ev in self.associated_events]
1349 def ly_expression_pre_note (self, is_chord_element):
1350 res = string.join (self.pre_note_ly (is_chord_element), ' ')
1355 def get_length (self):
1356 return self.duration.get_length()
1358 def get_properties (self):
1359 return ("'duration %s"
1360 % self.duration.lisp_expression ())
1362 class RestEvent (RhythmicEvent):
1363 def __init__ (self):
1364 RhythmicEvent.__init__ (self)
1367 def ly_expression (self):
1368 res = self.ly_expression_pre_note (False)
1370 return res + "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
1372 return 'r%s' % self.duration.ly_expression ()
1374 def print_ly (self, printer):
1375 for ev in self.associated_events:
1376 ev.print_ly (printer)
1378 self.pitch.print_ly (printer)
1379 self.duration.print_ly (printer)
1383 self.duration.print_ly (printer)
1385 class SkipEvent (RhythmicEvent):
1386 def ly_expression (self):
1387 return 's%s' % self.duration.ly_expression ()
1389 class NoteEvent(RhythmicEvent):
1390 def __init__ (self):
1391 RhythmicEvent.__init__ (self)
1393 self.drum_type = None
1394 self.cautionary = False
1395 self.forced_accidental = False
1397 def get_properties (self):
1398 str = RhythmicEvent.get_properties (self)
1401 str += self.pitch.lisp_expression ()
1402 elif self.drum_type:
1403 str += "'drum-type '%s" % self.drum_type
1407 def pitch_mods (self):
1410 excl_question += '?'
1411 if self.forced_accidental:
1412 excl_question += '!'
1414 return excl_question
1416 def ly_expression (self):
1417 # obtain all stuff that needs to be printed before the note:
1418 res = self.ly_expression_pre_note (True)
1420 return res + '%s%s%s' % (self.pitch.ly_expression (),
1422 self.duration.ly_expression ())
1423 elif self.drum_type:
1424 return res + '%s%s' (self.drum_type,
1425 self.duration.ly_expression ())
1427 def chord_element_ly (self):
1428 # obtain all stuff that needs to be printed before the note:
1429 res = self.ly_expression_pre_note (True)
1431 return res + '%s%s' % (self.pitch.ly_expression (),
1433 elif self.drum_type:
1434 return res + '%s%s' (self.drum_type)
1437 def print_ly (self, printer):
1438 for ev in self.associated_events:
1439 ev.print_ly (printer)
1441 self.pitch.print_ly (printer)
1442 printer (self.pitch_mods ())
1444 printer (self.drum_type)
1446 self.duration.print_ly (printer)
1448 class KeySignatureChange (Music):
1449 def __init__ (self):
1450 Music.__init__ (self)
1453 self.non_standard_alterations = None
1455 def format_non_standard_alteration (self, a):
1456 alter_dict = { -2: ",DOUBLE-FLAT",
1457 -1.5: ",THREE-Q-FLAT",
1463 1.5: ",THREE-Q-SHARP",
1466 accidental = alter_dict[a[1]]
1468 warning (_ ("Unable to convert alteration %s to a lilypond expression") % a[1])
1471 return "( %s . %s )" % (a[0], accidental)
1473 return "(( %s . %s ) . %s )" % (a[2], a[0], accidental)
1477 def ly_expression (self):
1479 return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
1481 elif self.non_standard_alterations:
1482 alterations = [self.format_non_standard_alteration (a) for
1483 a in self.non_standard_alterations]
1484 return "\\set Staff.keySignature = #`(%s)" % string.join (alterations, " ")
1488 class TimeSignatureChange (Music):
1489 def __init__ (self):
1490 Music.__init__ (self)
1491 self.fractions = [4,4]
1493 def format_fraction (self, frac):
1494 if isinstance (frac, list):
1495 l = [self.format_fraction (f) for f in frac]
1496 return "(" + string.join (l, " ") + ")"
1500 def ly_expression (self):
1502 # Print out the style if we have ome, but the '() should only be
1503 # forced for 2/2 or 4/4, since in all other cases we'll get numeric
1504 # signatures anyway despite the default 'C signature style!
1505 is_common_signature = self.fractions in ([2,2], [4,4], [4,2])
1507 if self.style == "common":
1508 st = "\\defaultTimeSignature"
1509 elif (self.style != "'()"):
1510 st = "\\once \\override Staff.TimeSignature #'style = #%s " % self.style
1511 elif (self.style != "'()") or is_common_signature:
1512 st = "\\numericTimeSignature"
1514 # Easy case: self.fractions = [n,d] => normal \time n/d call:
1515 if len (self.fractions) == 2 and isinstance (self.fractions[0], int):
1516 return st + '\\time %d/%d ' % tuple (self.fractions)
1517 elif self.fractions:
1518 return st + "\\compoundMeter #'%s" % self.format_fraction (self.fractions)
1522 class ClefChange (Music):
1523 def __init__ (self):
1524 Music.__init__ (self)
1529 def octave_modifier (self):
1530 return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
1531 def clef_name (self):
1532 return {('G', 2): "treble",
1534 ('C', 1): "soprano",
1535 ('C', 2): "mezzosoprano",
1538 ('C', 5): "baritone",
1539 ('F', 3): "varbaritone",
1541 ('F', 5): "subbass",
1542 ("percussion", 2): "percussion",
1543 # Workaround: MuseScore uses PERC instead of percussion
1544 ("PERC", 2): "percussion",
1545 ("TAB", 5): "tab"}.get ((self.type, self.position), None)
1546 def ly_expression (self):
1547 return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
1550 "G": ("clefs.G", -2, -6),
1551 "C": ("clefs.C", 0, 0),
1552 "F": ("clefs.F", 2, 6),
1555 def lisp_expression (self):
1557 (glyph, pos, c0) = self.clef_dict[self.type]
1561 (make-music 'SequentialMusic
1564 (make-property-set 'clefGlyph "%s") 'Staff)
1566 (make-property-set 'clefPosition %d) 'Staff)
1568 (make-property-set 'middleCPosition %d) 'Staff)))
1569 """ % (glyph, pos, c0)
1572 class Transposition (Music):
1573 def __init__ (self):
1574 Music.__init__ (self)
1576 def ly_expression (self):
1577 self.pitch._force_absolute_pitch = True
1578 return '\\transposition %s' % self.pitch.ly_expression ()
1580 class StaffChange (Music):
1581 def __init__ (self, staff):
1582 Music.__init__ (self)
1584 def ly_expression (self):
1586 return "\\change Staff=\"%s\"" % self.staff
1590 class SetEvent (Music):
1591 def __init__ (self, contextprop, value):
1592 Music.__init__ (self)
1593 self.context_prop = contextprop
1595 def ly_expression (self):
1597 return "\\set %s = %s" % (self.context_prop, self.value)
1601 class StaffLinesEvent (Music):
1602 def __init__ (self, lines):
1603 Music.__init__ (self)
1605 def ly_expression (self):
1606 if (self.lines > 0):
1607 return "\\stopStaff \\override Staff.StaffSymbol #'line-count = #%s \\startStaff" % self.lines
1609 return "\\stopStaff \\revert Staff.StaffSymbol #'line-count \\startStaff"
1611 class TempoMark (Music):
1612 def __init__ (self):
1613 Music.__init__ (self)
1614 self.baseduration = None
1615 self.newduration = None
1617 self.parentheses = False
1618 def set_base_duration (self, dur):
1619 self.baseduration = dur
1620 def set_new_duration (self, dur):
1621 self.newduration = dur
1622 def set_beats_per_minute (self, beats):
1624 def set_parentheses (self, parentheses):
1625 self.parentheses = parentheses
1626 def wait_for_note (self):
1628 def duration_to_markup (self, dur):
1630 # Generate the markup to print the note, use scheme mode for
1631 # ly_expression to get longa and not \longa (which causes an error)
1632 return "\\general-align #Y #DOWN \\smaller \\note #\"%s\" #UP" % dur.ly_expression(None, True)
1635 def tempo_markup_template (self):
1636 return "\\mark\\markup { \\fontsize #-2 \\line { %s } }"
1637 def ly_expression (self):
1639 if not self.baseduration:
1642 if self.parentheses:
1643 res += "\\tempo \"\" %s=%s" % (self.baseduration.ly_expression(), self.beats)
1645 res += "\\tempo %s=%s" % (self.baseduration.ly_expression(), self.beats)
1646 elif self.newduration:
1647 dm = self.duration_to_markup (self.baseduration)
1648 ndm = self.duration_to_markup (self.newduration)
1649 if self.parentheses:
1650 contents = "\"(\" %s = %s \")\"" % (dm, ndm)
1652 contents = " %s = %s " % (dm, ndm)
1653 res += self.tempo_markup_template() % contents
1658 class FiguredBassNote (Music):
1659 def __init__ (self):
1660 Music.__init__ (self)
1664 def set_prefix (self, prefix):
1665 self.prefix = prefix
1666 def set_suffix (self, suffix):
1667 self.prefix = suffix
1668 def set_number (self, number):
1669 self.number = number
1670 def ly_expression (self):
1683 class FiguredBassEvent (NestedMusic):
1684 def __init__ (self):
1685 NestedMusic.__init__ (self)
1686 self.duration = None
1687 self.real_duration = 0
1688 self.parentheses = False
1690 def set_duration (self, dur):
1692 def set_parentheses (self, par):
1693 self.parentheses = par
1694 def set_real_duration (self, dur):
1695 self.real_duration = dur
1697 def print_ly (self, printer):
1698 figured_bass_events = [e for e in self.elements if
1699 isinstance (e, FiguredBassNote)]
1700 if figured_bass_events:
1702 for x in figured_bass_events:
1703 notes.append (x.ly_expression ())
1704 contents = string.join (notes)
1705 if self.parentheses:
1706 contents = '[%s]' % contents
1707 printer ('<%s>' % contents)
1708 self.duration.print_ly (printer)
1711 class MultiMeasureRest(Music):
1713 def lisp_expression (self):
1716 'MultiMeasureRestMusicGroup
1718 (list (make-music (quote BarCheck))
1723 'MultiMeasureRestEvent
1726 (make-music (quote BarCheck))))
1727 """ % self.duration.lisp_expression ()
1729 def ly_expression (self):
1730 return 'R%s' % self.duration.ly_expression ()
1733 class Break (Music):
1734 def __init__ (self, tp="break"):
1735 Music.__init__ (self)
1737 def print_ly (self, printer):
1739 printer.dump ("\\%s" % self.type)
1742 def __init__ (self, command = "StaffGroup"):
1743 self.stafftype = command
1745 self.instrument_name = None
1746 self.short_instrument_name = None
1750 self.is_group = True
1751 self.context_modifications = []
1752 # part_information is a list with entries of the form
1753 # [staffid, voicelist]
1754 # where voicelist is a list with entries of the form
1755 # [voiceid1, [lyricsid11, lyricsid12,...] ]
1756 self.part_information = None
1758 def append_staff (self, staff):
1759 self.children.append (staff)
1761 def set_part_information (self, part_name, staves_info):
1762 if part_name == self.id:
1763 self.part_information = staves_info
1765 for c in self.children:
1766 c.set_part_information (part_name, staves_info)
1768 def add_context_modification (self, modification):
1769 self.context_modifications.append (modification)
1771 def print_ly_contents (self, printer):
1772 for c in self.children:
1774 c.print_ly (printer)
1775 def needs_with (self):
1777 needs_with |= self.spanbar == "no"
1778 needs_with |= self.instrument_name != None
1779 needs_with |= self.short_instrument_name != None
1780 needs_with |= (self.symbol != None) and (self.symbol != "bracket")
1782 def print_ly_context_mods (self, printer):
1783 if self.instrument_name or self.short_instrument_name:
1784 printer.dump ("\\consists \"Instrument_name_engraver\"")
1785 if self.spanbar == "no":
1786 printer.dump ("\\override SpanBar #'transparent = ##t")
1787 brack = {"brace": "SystemStartBrace",
1789 "line": "SystemStartSquare"}.get (self.symbol, None)
1791 printer.dump ("systemStartDelimiter = #'%s" % brack)
1793 def print_ly_overrides (self, printer):
1794 needs_with = self.needs_with () | (len (self.context_modifications) > 0);
1796 printer.dump ("\\with {")
1797 self.print_ly_context_mods (printer)
1798 for m in self.context_modifications:
1802 def print_ly (self, printer):
1804 printer.dump ("\\new %s" % self.stafftype)
1805 self.print_ly_overrides (printer)
1808 if self.stafftype and self.instrument_name:
1809 printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
1810 escape_instrument_string (self.instrument_name)))
1812 if self.stafftype and self.short_instrument_name:
1813 printer.dump ("\\set %s.shortInstrumentName = %s" % (self.stafftype,
1814 escape_instrument_string (self.short_instrument_name)))
1816 self.print_ly_contents (printer)
1822 class Staff (StaffGroup):
1823 def __init__ (self, command = "Staff"):
1824 StaffGroup.__init__ (self, command)
1825 self.is_group = False
1827 self.voice_command = "Voice"
1828 self.substafftype = None
1830 def needs_with (self):
1832 def print_ly_context_mods (self, printer):
1835 def print_ly_contents (self, printer):
1836 if not self.id or not self.part_information:
1838 sub_staff_type = self.substafftype
1839 if not sub_staff_type:
1840 sub_staff_type = self.stafftype
1842 for [staff_id, voices] in self.part_information:
1843 # Chord names need to come before the staff itself!
1844 for [v, lyrics, figuredbass, chordnames] in voices:
1846 printer ('\context ChordNames = "%s" \\%s' % (chordnames, chordnames))
1848 # now comes the real staff definition:
1850 printer ('\\context %s = "%s" << ' % (sub_staff_type, staff_id))
1852 printer ('\\context %s << ' % sub_staff_type)
1855 nr_voices = len (voices)
1856 for [v, lyrics, figuredbass, chordnames] in voices:
1858 voice_count_text = ''
1860 voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo',
1861 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
1862 printer ('\\context %s = "%s" {%s \\%s }' % (self.voice_command, v, voice_count_text, v))
1866 printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
1869 printer ('\context FiguredBass = "%s" \\%s' % (figuredbass, figuredbass))
1872 def print_ly (self, printer):
1873 if self.part_information and len (self.part_information) > 1:
1874 self.stafftype = "PianoStaff"
1875 self.substafftype = "Staff"
1876 StaffGroup.print_ly (self, printer)
1878 class TabStaff (Staff):
1879 def __init__ (self, command = "TabStaff"):
1880 Staff.__init__ (self, command)
1881 self.string_tunings = []
1882 self.tablature_format = None
1883 self.voice_command = "TabVoice"
1884 def print_ly_overrides (self, printer):
1885 if self.string_tunings or self.tablature_format:
1886 printer.dump ("\\with {")
1887 if self.string_tunings:
1888 printer.dump ("stringTunings = #`(")
1889 for i in self.string_tunings:
1890 printer.dump (",%s" % i.lisp_expression ())
1892 if self.tablature_format:
1893 printer.dump ("tablatureFormat = #%s" % self.tablature_format)
1897 class DrumStaff (Staff):
1898 def __init__ (self, command = "DrumStaff"):
1899 Staff.__init__ (self, command)
1900 self.drum_style_table = None
1901 self.voice_command = "DrumVoice"
1902 def print_ly_overrides (self, printer):
1903 if self.drum_style_table:
1904 printer.dump ("\with {")
1905 printer.dump ("drumStyleTable = #%s" % self.drum_style_table)
1908 class RhythmicStaff (Staff):
1909 def __init__ (self, command = "RhythmicStaff"):
1910 Staff.__init__ (self, command)
1913 def __init__ (self):
1914 self.contents = None
1915 self.create_midi = False
1917 def set_contents (self, contents):
1918 self.contents = contents
1920 def set_part_information (self, part_id, staves_info):
1922 self.contents.set_part_information (part_id, staves_info)
1924 def print_ly (self, printer):
1925 printer.dump ("\\score {");
1928 self.contents.print_ly (printer);
1929 printer.dump ("\\layout {}");
1931 if not self.create_midi:
1932 printer.dump ("% To create MIDI output, uncomment the following line:");
1934 printer.dump ("% ");
1935 printer.dump ("\\midi {}");
1943 bflat.alteration = -1
1953 print bflat.semitones()
1954 print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
1955 print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
1957 print bflat.semitones(), 'down'
1958 print bflat.transposed (down)
1959 print bflat.transposed (down).transposed (down)
1960 print bflat.transposed (down).transposed (down).transposed (down)
1964 def test_printer ():
1972 m = SequentialMusic()
1973 m.append (make_note ())
1974 m.append (make_note ())
1975 m.append (make_note ())
1978 t = TimeScaledMusic ()
1984 m = SequentialMusic ()
1985 m.append (make_tup ())
1986 m.append (make_tup ())
1987 m.append (make_tup ())
1989 printer = Output_printer()
1990 m.print_ly (printer)
1994 m = SequentialMusic()
1998 n.duration.duration_log = l
2000 evc.insert_around (None, n, 0)
2001 m.insert_around (None, evc, 0)
2005 n.duration.duration_log = l
2007 evc.insert_around (None, n, 0)
2008 m.insert_around (None, evc, 0)
2012 n.duration.duration_log = l
2014 evc.insert_around (None, n, 0)
2015 m.insert_around (None, evc, 0)
2019 m.insert_around (None, evc, 0)
2024 tonic.alteration = -2
2025 n = KeySignatureChange()
2026 n.tonic=tonic.copy()
2027 n.scale = [0, 0, -2, 0, 0,-2,-2]
2029 evc.insert_around (None, n, 0)
2030 m.insert_around (None, evc, 0)
2035 if __name__ == '__main__':
2041 expr.set_start (Rational (0))
2042 print expr.ly_expression()
2043 start = Rational (0,4)
2044 stop = Rational (4,2)
2045 def sub(x, start=start, stop=stop):
2046 ok = x.start >= start and x.start +x.get_length() <= stop
2049 print expr.lisp_sub_expression(sub)