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 def escape_instrument_string (input_string):
18 retstring = string.replace (input_string, "\"", "\\\"")
19 if re.match ('.*[\r\n]+.*', retstring):
20 rx = re.compile (r'[\n\r]+')
21 strings = rx.split (retstring)
22 retstring = "\\markup { \\column { "
24 retstring += "\\line {\"" + s + "\"} "
27 retstring = "\"" + retstring + "\""
30 class Output_stack_element:
32 self.factor = Rational (1)
34 o = Output_stack_element()
35 o.factor = self.factor
40 """A class that takes care of formatting (eg.: indenting) a
41 Music expression as a .ly file.
49 self._file = sys.stdout
51 self._output_state_stack = [Output_stack_element()]
52 self._skipspace = False
53 self._last_duration = None
55 def set_file (self, file):
58 def dump_version (self):
60 self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
63 def get_indent (self):
64 return self._nesting * self._indent
67 last = self._output_state_stack[-1]
68 self._output_state_stack.append (last.copy())
70 def add_factor (self, factor):
72 self._output_state_stack[-1].factor *= factor
75 del self._output_state_stack[-1]
76 if not self._output_state_stack:
79 def duration_factor (self):
80 return self._output_state_stack[-1].factor
82 def print_verbatim (self, str):
85 def unformatted_output (self, str):
86 # don't indent on \< and indent only once on <<
87 self._nesting += ( str.count ('<')
88 - str.count ('\<') - str.count ('<<')
90 self._nesting -= ( str.count ('>') - str.count ('\>') - str.count ('>>')
91 - str.count ('->') - str.count ('_>')
94 self.print_verbatim (str)
96 def print_duration_string (self, str):
97 if self._last_duration == str:
100 self.unformatted_output (str)
102 def add_word (self, str):
103 if (len (str) + 1 + len (self._line) > self._line_len):
105 self._skipspace = True
107 if not self._skipspace:
109 self.unformatted_output (str)
110 self._skipspace = False
113 self._file.write (self._line + '\n')
114 self._line = ' ' * self._indent * self._nesting
115 self._skipspace = True
117 def skipspace (self):
118 self._skipspace = True
120 def __call__(self, arg):
123 def dump (self, str):
125 self._skipspace = False
126 self.unformatted_output (str)
128 words = string.split (str)
141 self.duration_log = 0
143 self.factor = Rational (1)
145 def lisp_expression (self):
146 return '(ly:make-duration %d %d %d %d)' % (self.duration_log,
148 self.factor.numerator (),
149 self.factor.denominator ())
152 def ly_expression (self, factor = None, scheme_mode = False):
156 if self.duration_log < 0:
158 longer_dict = {-1: "breve", -2: "longa"}
160 longer_dict = {-1: "\\breve", -2: "\\longa"}
161 str = longer_dict.get (self.duration_log, "1")
163 str = '%d' % (1 << self.duration_log)
166 if factor <> Rational (1,1):
167 if factor.denominator () <> 1:
168 str += '*%d/%d' % (factor.numerator (), factor.denominator ())
170 str += '*%d' % factor.numerator ()
174 def print_ly (self, outputter):
175 str = self.ly_expression (self.factor / outputter.duration_factor ())
176 outputter.print_duration_string (str)
179 return self.ly_expression()
184 d.duration_log = self.duration_log
185 d.factor = self.factor
188 def get_length (self):
189 dot_fact = Rational( (1 << (1 + self.dots))-1,
192 log = abs (self.duration_log)
194 if self.duration_log < 0:
195 base = Rational (dur)
197 base = Rational (1, dur)
199 return base * dot_fact * self.factor
202 # Implement the different note names for the various languages
203 def pitch_generic (pitch, notenames, accidentals):
204 str = notenames[pitch.step]
205 halftones = int (pitch.alteration)
207 str += accidentals[0] * (-halftones)
208 elif pitch.alteration > 0:
209 str += accidentals[3] * (halftones)
210 # Handle remaining fraction to pitch.alteration (for microtones)
211 if (halftones != pitch.alteration):
212 if None in accidentals[1:3]:
213 ly.warning (_ ("Language does not support microtones contained in the piece"))
216 str += {-0.5: accidentals[1], 0.5: accidentals[2]}[pitch.alteration-halftones]
218 ly.warning (_ ("Language does not support microtones contained in the piece"))
221 def pitch_general (pitch):
222 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['es', 'eh', 'ih', 'is'])
223 return str.replace ('aes', 'as').replace ('ees', 'es')
225 def pitch_nederlands (pitch):
226 return pitch_general (pitch)
228 def pitch_english (pitch):
229 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['f', 'qf', 'qs', 's'])
230 return str.replace ('aes', 'as').replace ('ees', 'es')
232 def pitch_deutsch (pitch):
233 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['es', 'eh', 'ih', 'is'])
234 return str.replace ('hes', 'b').replace ('aes', 'as').replace ('ees', 'es')
236 def pitch_norsk (pitch):
237 return pitch_deutsch (pitch)
239 def pitch_svenska (pitch):
240 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['ess', None, None, 'iss'])
241 return str.replace ('hess', 'b').replace ('aes', 'as').replace ('ees', 'es')
243 def pitch_italiano (pitch):
244 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', 'sb', 'sd', 'd'])
247 def pitch_catalan (pitch):
248 return pitch_italiano (pitch)
250 def pitch_espanol (pitch):
251 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 's'])
254 def pitch_vlaams (pitch):
255 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 'k'])
258 def set_pitch_language (language):
259 global pitch_generating_function
261 "nederlands": pitch_nederlands,
262 "english": pitch_english,
263 "deutsch": pitch_deutsch,
264 "norsk": pitch_norsk,
265 "svenska": pitch_svenska,
266 "italiano": pitch_italiano,
267 "catalan": pitch_catalan,
268 "espanol": pitch_espanol,
269 "vlaams": pitch_vlaams}
270 pitch_generating_function = function_dict.get (language, pitch_general)
272 # global variable to hold the formatting function.
273 pitch_generating_function = pitch_general
281 self._force_absolute_pitch = False
284 return self.ly_expression()
286 def transposed (self, interval):
288 c.alteration += interval.alteration
289 c.step += interval.step
290 c.octave += interval.octave
293 target_st = self.semitones() + interval.semitones()
294 c.alteration += target_st - c.semitones()
301 c.octave += c.step / 7
304 def lisp_expression (self):
305 return '(ly:make-pitch %d %d %d)' % (self.octave,
311 p.alteration = self.alteration
313 p.octave = self.octave
317 return self.step + self.octave *7
319 def semitones (self):
320 return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
322 def ly_step_expression (self):
323 return pitch_generating_function (self)
325 def absolute_pitch (self):
327 return "'" * (self.octave + 1)
328 elif self.octave < -1:
329 return "," * (-self.octave - 1)
333 def relative_pitch (self):
334 global previous_pitch
335 if not previous_pitch:
336 previous_pitch = self
337 return self.absolute_pitch ()
338 previous_pitch_steps = previous_pitch.octave * 7 + previous_pitch.step
339 this_pitch_steps = self.octave * 7 + self.step
340 pitch_diff = (this_pitch_steps - previous_pitch_steps)
341 previous_pitch = self
343 return "'" * ((pitch_diff + 3) / 7)
344 elif pitch_diff < -3:
345 return "," * ((-pitch_diff + 3) / 7)
349 def ly_expression (self):
350 str = self.ly_step_expression ()
351 if relative_pitches and not self._force_absolute_pitch:
352 str += self.relative_pitch ()
354 str += self.absolute_pitch ()
358 def print_ly (self, outputter):
359 outputter (self.ly_expression())
364 self.start = Rational (0)
366 self.identifier = None
368 def get_length(self):
371 def get_properties (self):
374 def has_children (self):
377 def get_index (self):
379 return self.parent.elements.index (self)
383 return self.__class__.__name__
385 def lisp_expression (self):
388 props = self.get_properties ()
390 return "(make-music '%s %s)" % (name, props)
392 def set_start (self, start):
395 def find_first (self, predicate):
400 def print_comment (self, printer, text = None):
411 lines = string.split (text, '\n')
414 printer.unformatted_output ('% ' + l)
418 def print_with_identifier (self, printer):
420 printer ("\\%s" % self.identifier)
422 self.print_ly (printer)
424 def print_ly (self, printer):
425 printer (self.ly_expression ())
427 class MusicWrapper (Music):
431 def print_ly (self, func):
432 self.element.print_ly (func)
434 class ModeChangingMusicWrapper (MusicWrapper):
436 MusicWrapper.__init__ (self)
437 self.mode = 'notemode'
439 def print_ly (self, func):
440 func ('\\%s' % self.mode)
441 MusicWrapper.print_ly (self, func)
443 class RelativeMusic (MusicWrapper):
445 MusicWrapper.__init__ (self)
446 self.basepitch = None
448 def print_ly (self, func):
449 global previous_pitch
450 global relative_pitches
451 prev_relative_pitches = relative_pitches
452 relative_pitches = True
453 previous_pitch = self.basepitch
454 if not previous_pitch:
455 previous_pitch = Pitch ()
456 func ('\\relative %s%s' % (pitch_generating_function (previous_pitch),
457 previous_pitch.absolute_pitch ()))
458 MusicWrapper.print_ly (self, func)
459 relative_pitches = prev_relative_pitches
461 class TimeScaledMusic (MusicWrapper):
463 MusicWrapper.__init__ (self)
466 self.display_number = "actual" # valid values "actual" | "both" | None
467 # Display the basic note length for the tuplet:
468 self.display_type = None # value values "actual" | "both" | None
469 self.display_bracket = "bracket" # valid values "bracket" | "curved" | None
470 self.actual_type = None # The actually played unit of the scaling
471 self.normal_type = None # The basic unit of the scaling
472 self.display_numerator = None
473 self.display_denominator = None
475 def print_ly (self, func):
476 if self.display_bracket == None:
477 func ("\\once \\override TupletBracket #'stencil = ##f")
479 elif self.display_bracket == "curved":
480 ly.warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
481 func ("\\once \\override TupletBracket #'stencil = #ly:slur::print")
484 base_number_function = {None: "#f",
485 "actual": "tuplet-number::calc-denominator-text",
486 "both": "tuplet-number::calc-fraction-text"}.get (self.display_number, None)
487 # If we have non-standard numerator/denominator, use our custom function
488 if self.display_number == "actual" and self.display_denominator:
489 base_number_function = "(tuplet-number::non-default-tuplet-denominator-text %s)" % self.display_denominator
490 elif self.display_number == "both" and (self.display_denominator or self.display_numerator):
491 if self.display_numerator:
492 num = self.display_numerator
495 if self.display_denominator:
496 den = self.display_denominator
499 base_number_function = "(tuplet-number::non-default-tuplet-fraction-text %s %s)" % (den, num)
502 if self.display_type == "actual" and self.normal_type:
503 # Obtain the note duration in scheme-mode, i.e. \longa as \\longa
504 base_duration = self.normal_type.ly_expression (None, True)
505 func ("\\once \\override TupletNumber #'text = #(tuplet-number::append-note-wrapper %s \"%s\")" %
506 (base_number_function, base_duration))
508 elif self.display_type == "both": # TODO: Implement this using actual_type and normal_type!
509 if self.display_number == None:
510 func ("\\once \\override TupletNumber #'stencil = ##f")
512 elif self.display_number == "both":
513 den_duration = self.normal_type.ly_expression (None, True)
514 # If we don't have an actual type set, use the normal duration!
516 num_duration = self.actual_type.ly_expression (None, True)
518 num_duration = den_duration
519 if (self.display_denominator or self.display_numerator):
520 func ("\\once \\override TupletNumber #'text = #(tuplet-number::non-default-fraction-with-notes %s \"%s\" %s \"%s\")" %
521 (self.display_denominator, den_duration,
522 self.display_numerator, num_duration))
525 func ("\\once \\override TupletNumber #'text = #(tuplet-number::fraction-with-notes \"%s\" \"%s\")" %
526 (den_duration, num_duration))
529 if self.display_number == None:
530 func ("\\once \\override TupletNumber #'stencil = ##f")
532 elif self.display_number == "both":
533 func ("\\once \\override TupletNumber #'text = #%s" % base_number_function)
536 func ('\\times %d/%d ' %
537 (self.numerator, self.denominator))
538 func.add_factor (Rational (self.numerator, self.denominator))
539 MusicWrapper.print_ly (self, func)
542 class NestedMusic(Music):
544 Music.__init__ (self)
547 def append (self, what):
549 self.elements.append (what)
551 def has_children (self):
554 def insert_around (self, succ, elt, dir):
555 assert elt.parent == None
556 assert succ == None or succ in self.elements
561 idx = self.elements.index (succ)
568 idx = len (self.elements)
570 self.elements.insert (idx, elt)
573 def get_properties (self):
574 return ("'elements (list %s)"
575 % string.join (map (lambda x: x.lisp_expression(),
578 def get_subset_properties (self, predicate):
579 return ("'elements (list %s)"
580 % string.join (map (lambda x: x.lisp_expression(),
581 filter ( predicate, self.elements))))
582 def get_neighbor (self, music, dir):
583 assert music.parent == self
584 idx = self.elements.index (music)
586 idx = min (idx, len (self.elements) -1)
589 return self.elements[idx]
591 def delete_element (self, element):
592 assert element in self.elements
594 self.elements.remove (element)
595 element.parent = None
597 def set_start (self, start):
599 for e in self.elements:
602 def find_first (self, predicate):
603 r = Music.find_first (self, predicate)
607 for e in self.elements:
608 r = e.find_first (predicate)
613 class SequentialMusic (NestedMusic):
614 def get_last_event_chord (self):
616 at = len( self.elements ) - 1
618 not isinstance (self.elements[at], ChordEvent) and
619 not isinstance (self.elements[at], BarLine)):
622 if (at >= 0 and isinstance (self.elements[at], ChordEvent)):
623 value = self.elements[at]
626 def print_ly (self, printer, newline = True):
629 self.print_comment (printer)
633 for e in self.elements:
640 def lisp_sub_expression (self, pred):
644 props = self.get_subset_properties (pred)
646 return "(make-music '%s %s)" % (name, props)
648 def set_start (self, start):
649 for e in self.elements:
651 start += e.get_length()
655 self.repeat_type = "volta"
656 self.repeat_count = 2
659 def set_music (self, music):
660 if isinstance (music, Music):
662 elif isinstance (music, list):
663 self.music = SequentialMusic ()
664 self.music.elements = music
666 ly.warning (_ ("unable to set the music %(music)s for the repeat %(repeat)s") % \
667 {'music':music, 'repeat':self})
668 def add_ending (self, music):
669 self.endings.append (music)
670 def print_ly (self, printer):
671 printer.dump ('\\repeat %s %s' % (self.repeat_type, self.repeat_count))
673 self.music.print_ly (printer)
675 ly.warning (_ ("encountered repeat without body"))
678 printer.dump ('\\alternative {')
679 for e in self.endings:
686 self.lyrics_syllables = []
688 def print_ly (self, printer):
689 printer.dump ("\lyricmode {")
690 for l in self.lyrics_syllables:
691 printer.dump ( "%s " % l )
694 def ly_expression (self):
695 lstr = "\lyricmode {\n "
696 for l in self.lyrics_syllables:
704 self.header_fields = {}
705 def set_field (self, field, value):
706 self.header_fields[field] = value
708 def print_ly (self, printer):
709 printer.dump ("\header {")
711 for (k,v) in self.header_fields.items ():
713 printer.dump ('%s = %s' % (k,v))
722 self.global_staff_size = -1
725 self.page_height = -1
728 self.bottom_margin = -1
729 self.left_margin = -1
730 self.right_margin = -1
731 self.system_left_margin = -1
732 self.system_right_margin = -1
733 self.system_distance = -1
734 self.top_system_distance = -1
736 def print_length_field (self, printer, field, value):
738 printer.dump ("%s = %s\\cm" % (field, value))
740 def print_ly (self, printer):
741 if self.global_staff_size > 0:
742 printer.dump ('#(set-global-staff-size %s)' % self.global_staff_size)
744 printer.dump ('\\paper {')
746 self.print_length_field (printer, "paper-width", self.page_width)
747 self.print_length_field (printer, "paper-height", self.page_height)
748 self.print_length_field (printer, "top-margin", self.top_margin)
749 self.print_length_field (printer, "bottom-margin", self.bottom_margin)
750 self.print_length_field (printer, "left-margin", self.left_margin)
751 # TODO: maybe set line-width instead of right-margin?
752 self.print_length_field (printer, "right-margin", self.right_margin)
753 # TODO: What's the corresponding setting for system_left_margin and
754 # system_right_margin in LilyPond?
755 self.print_length_field (printer, "between-system-space", self.system_distance)
756 self.print_length_field (printer, "page-top-space", self.top_system_distance)
763 self.context_dict = {}
764 def add_context (self, context):
765 if not self.context_dict.has_key (context):
766 self.context_dict[context] = []
767 def set_context_item (self, context, item):
768 self.add_context (context)
769 if not item in self.context_dict[context]:
770 self.context_dict[context].append (item)
771 def print_ly (self, printer):
772 if self.context_dict.items ():
773 printer.dump ('\\layout {')
775 for (context, defs) in self.context_dict.items ():
776 printer.dump ('\\context { \\%s' % context)
787 class ChordEvent (NestedMusic):
789 NestedMusic.__init__ (self)
790 self.after_grace_elements = None
791 self.grace_elements = None
792 self.grace_type = None
793 def append_grace (self, element):
795 if not self.grace_elements:
796 self.grace_elements = SequentialMusic ()
797 self.grace_elements.append (element)
798 def append_after_grace (self, element):
800 if not self.after_grace_elements:
801 self.after_grace_elements = SequentialMusic ()
802 self.after_grace_elements.append (element)
804 def has_elements (self):
805 return [e for e in self.elements if
806 isinstance (e, NoteEvent) or isinstance (e, RestEvent)] != []
809 def get_length (self):
811 for e in self.elements:
812 l = max(l, e.get_length())
815 def get_duration (self):
816 note_events = [e for e in self.elements if
817 isinstance (e, NoteEvent) or isinstance (e, RestEvent)]
819 return note_events[0].duration
823 def print_ly (self, printer):
824 note_events = [e for e in self.elements if
825 isinstance (e, NoteEvent)]
827 rest_events = [e for e in self.elements if
828 isinstance (e, RhythmicEvent)
829 and not isinstance (e, NoteEvent)]
831 other_events = [e for e in self.elements if
832 not isinstance (e, RhythmicEvent)]
834 if self.after_grace_elements:
835 printer ('\\afterGrace {')
837 if self.grace_elements and self.elements:
839 printer ('\\%s' % self.grace_type)
842 # don't print newlines after the { and } braces
843 self.grace_elements.print_ly (printer, False)
844 elif self.grace_elements: # no self.elements!
845 ly.warning (_ ("Grace note with no following music: %s") % self.grace_elements)
847 printer ('\\%s' % self.grace_type)
850 self.grace_elements.print_ly (printer, False)
853 # Print all overrides and other settings needed by the
854 # articulations/ornaments before the note
855 for e in other_events:
856 e.print_before_note (printer)
859 rest_events[0].print_ly (printer)
860 elif len (note_events) == 1:
861 note_events[0].print_ly (printer)
863 global previous_pitch
866 for x in note_events:
867 pitches.append (x.chord_element_ly ())
869 basepitch = previous_pitch
870 printer ('<%s>' % string.join (pitches))
871 previous_pitch = basepitch
872 duration = self.get_duration ()
874 duration.print_ly (printer)
878 for e in other_events:
881 for e in other_events:
882 e.print_after_note (printer)
884 if self.after_grace_elements:
886 self.after_grace_elements.print_ly (printer, False)
888 self.print_comment (printer)
890 class Partial (Music):
892 Music.__init__ (self)
894 def print_ly (self, printer):
896 printer.dump ("\\partial %s" % self.partial.ly_expression ())
898 class BarLine (Music):
900 Music.__init__ (self)
904 def print_ly (self, printer):
905 bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': "dashed",
906 'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
907 'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'",
908 'short': "'", 'none': "" }.get (self.type, None)
909 if bar_symbol <> None:
910 printer.dump ('\\bar "%s"' % bar_symbol)
914 if self.bar_number > 0 and (self.bar_number % 10) == 0:
915 printer.dump ("\\barNumberCheck #%d " % self.bar_number)
916 elif self.bar_number > 0:
917 printer.print_verbatim (' %% %d' % self.bar_number)
920 def ly_expression (self):
925 # strings to print before the note to which an event is attached.
926 # Ignored for notes etc.
927 self.before_note = None
928 self.after_note = None
929 # print something before the note to which an event is attached, e.g. overrides
930 def print_before_note (self, printer):
932 printer.dump (self.before_note)
933 # print something after the note to which an event is attached, e.g. resetting
934 def print_after_note (self, printer):
936 printer.dump (self.after_note)
939 class SpanEvent (Event):
941 Event.__init__ (self)
942 self.span_direction = 0 # start/stop
943 self.line_type = 'solid'
944 self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
945 self.size = 0 # size of e.g. ocrave shift
946 def wait_for_note (self):
948 def get_properties(self):
949 return "'span-direction %d" % self.span_direction
950 def set_span_type (self, type):
951 self.span_type = type
953 class SlurEvent (SpanEvent):
954 def print_before_note (self, printer):
955 command = {'dotted': '\\slurDotted',
956 'dashed' : '\\slurDashed'}.get (self.line_type, '')
957 if command and self.span_direction == -1:
958 printer.dump (command)
959 def print_after_note (self, printer):
960 # reset non-solid slur types!
961 command = {'dotted': '\\slurSolid',
962 'dashed' : '\\slurSolid'}.get (self.line_type, '')
963 if command and self.span_direction == -1:
964 printer.dump (command)
965 def ly_expression (self):
966 return {-1: '(', 1:')'}.get (self.span_direction, '')
968 class BeamEvent (SpanEvent):
969 def ly_expression (self):
970 return {-1: '[', 1:']'}.get (self.span_direction, '')
972 class PedalEvent (SpanEvent):
973 def ly_expression (self):
974 return {-1: '\\sustainOn',
975 0:'\\sustainOff\\sustainOn',
976 1:'\\sustainOff'}.get (self.span_direction, '')
978 class TextSpannerEvent (SpanEvent):
979 def ly_expression (self):
980 return {-1: '\\startTextSpan',
981 1:'\\stopTextSpan'}.get (self.span_direction, '')
983 class BracketSpannerEvent (SpanEvent):
984 # Ligature brackets use prefix-notation!!!
985 def print_before_note (self, printer):
986 if self.span_direction == -1:
988 # the bracket after the last note
989 def print_after_note (self, printer):
990 if self.span_direction == 1:
992 # we're printing everything in print_(before|after)_note...
993 def ly_expression (self):
997 class OctaveShiftEvent (SpanEvent):
998 def wait_for_note (self):
1000 def set_span_type (self, type):
1001 self.span_type = {'up': 1, 'down': -1}.get (type, 0)
1002 def ly_octave_shift_indicator (self):
1003 # convert 8/15 to lilypond indicators (+-1/+-2)
1005 value = {8: 1, 15: 2}[self.size]
1007 ly.warning (_ ("Invalid octave shift size found: %s. Using no shift.") % self.size)
1009 # negative values go up!
1010 value *= -1*self.span_type
1012 def ly_expression (self):
1013 dir = self.ly_octave_shift_indicator ()
1016 value = '\ottava #%s' % dir
1019 1: '\ottava #0'}.get (self.span_direction, '')
1021 class TrillSpanEvent (SpanEvent):
1022 def ly_expression (self):
1023 return {-1: '\\startTrillSpan',
1024 0: '', # no need to write out anything for type='continue'
1025 1:'\\stopTrillSpan'}.get (self.span_direction, '')
1027 class GlissandoEvent (SpanEvent):
1028 def print_before_note (self, printer):
1029 if self.span_direction == -1:
1031 "dashed" : "dashed-line",
1032 "dotted" : "dotted-line",
1034 }. get (self.line_type, None)
1036 printer.dump ("\\once \\override Glissando #'style = #'%s" % style)
1037 def ly_expression (self):
1038 return {-1: '\\glissando',
1039 1:''}.get (self.span_direction, '')
1041 class ArpeggioEvent(Event):
1042 def __init__ (self):
1043 Event.__init__ (self)
1045 self.non_arpeggiate = False
1046 def wait_for_note (self):
1048 def print_before_note (self, printer):
1049 if self.non_arpeggiate:
1050 printer.dump ("\\arpeggioBracket")
1052 dir = { -1: "\\arpeggioArrowDown", 1: "\\arpeggioArrowUp" }.get (self.direction, '')
1055 def print_after_note (self, printer):
1056 if self.non_arpeggiate or self.direction:
1057 printer.dump ("\\arpeggioNormal")
1058 def ly_expression (self):
1059 return ('\\arpeggio')
1062 class TieEvent(Event):
1063 def ly_expression (self):
1067 class HairpinEvent (SpanEvent):
1068 def set_span_type (self, type):
1069 self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
1070 def hairpin_to_ly (self):
1071 if self.span_direction == 1:
1074 return {1: '\<', -1: '\>'}.get (self.span_type, '')
1076 def ly_expression (self):
1077 return self.hairpin_to_ly ()
1079 def print_ly (self, printer):
1080 val = self.hairpin_to_ly ()
1086 class DynamicsEvent (Event):
1087 def __init__ (self):
1088 Event.__init__ (self)
1090 def wait_for_note (self):
1092 def ly_expression (self):
1094 return '\%s' % self.type
1098 def print_ly (self, printer):
1100 printer.dump ("\\%s" % self.type)
1102 class MarkEvent (Event):
1103 def __init__ (self, text="\\default"):
1104 Event.__init__ (self)
1106 def wait_for_note (self):
1108 def ly_contents (self):
1110 return '%s' % self.mark
1113 def ly_expression (self):
1114 return '\\mark %s' % self.ly_contents ()
1116 class MusicGlyphMarkEvent (MarkEvent):
1117 def ly_contents (self):
1119 return '\\markup { \\musicglyph #"scripts.%s" }' % self.mark
1124 class TextEvent (Event):
1125 def __init__ (self):
1126 Event.__init__ (self)
1128 self.force_direction = None
1130 def wait_for_note (self):
1133 def direction_mod (self):
1134 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
1136 def ly_expression (self):
1137 base_string = '%s\"%s\"'
1139 base_string = '%s\markup{ ' + self.markup + ' {%s} }'
1140 return base_string % (self.direction_mod (), self.text)
1142 class ArticulationEvent (Event):
1143 def __init__ (self):
1144 Event.__init__ (self)
1146 self.force_direction = None
1147 def wait_for_note (self):
1150 def direction_mod (self):
1151 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '')
1153 def ly_expression (self):
1154 return '%s\\%s' % (self.direction_mod (), self.type)
1156 class ShortArticulationEvent (ArticulationEvent):
1157 def direction_mod (self):
1159 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
1160 def ly_expression (self):
1162 return '%s%s' % (self.direction_mod (), self.type)
1166 class NoDirectionArticulationEvent (ArticulationEvent):
1167 def ly_expression (self):
1169 return '\\%s' % self.type
1173 class MarkupEvent (ShortArticulationEvent):
1174 def __init__ (self):
1175 ArticulationEvent.__init__ (self)
1176 self.contents = None
1177 def ly_expression (self):
1179 return "%s\\markup { %s }" % (self.direction_mod (), self.contents)
1183 class FretEvent (MarkupEvent):
1184 def __init__ (self):
1185 MarkupEvent.__init__ (self)
1186 self.force_direction = 1
1191 def ly_expression (self):
1193 if self.strings <> 6:
1194 val += "w:%s;" % self.strings
1196 val += "h:%s;" % self.frets
1197 if self.barre and len (self.barre) >= 3:
1198 val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2])
1199 have_fingering = False
1200 for i in self.elements:
1202 val += "%s-%s" % (i[0], i[1])
1204 have_fingering = True
1210 return "%s\\markup { \\fret-diagram #\"%s\" }" % (self.direction_mod (), val)
1215 class FunctionWrapperEvent (Event):
1216 def __init__ (self, function_name = None):
1217 Event.__init__ (self)
1218 self.function_name = function_name
1219 def pre_note_ly (self, is_chord_element):
1220 if self.function_name:
1221 return "\\%s" % self.function_name
1224 def pre_chord_ly (self):
1226 def ly_expression (self):
1227 if self.function_name:
1228 return "\\%s" % self.function_name
1232 class ParenthesizeEvent (FunctionWrapperEvent):
1233 def __init__ (self):
1234 FunctionWrapperEvent.__init__ (self, "parenthesize")
1236 class NotestyleEvent (Event):
1237 def __init__ (self):
1238 Event.__init__ (self)
1241 def pre_chord_ly (self):
1243 return "\\once \\override NoteHead #'style = #%s" % self.style
1246 def pre_note_ly (self, is_chord_element):
1247 if self.style and is_chord_element:
1248 return "\\tweak #'style #%s" % self.style
1251 def ly_expression (self):
1252 return self.pre_chord_ly ()
1256 def __init__ (self):
1260 return self.ly_expression()
1261 def ly_expression (self):
1262 return pitch_generating_function (self)
1264 class ChordModification:
1265 def __init__ (self):
1269 def ly_expression (self):
1271 val = {1: ".", -1: "^" }.get (self.type, "")
1272 val += "%s" % self.step
1273 val += {1: "+", -1: "-"}.get (self.alteration, "")
1278 class ChordNameEvent (Event):
1279 def __init__ (self):
1280 Event.__init__ (self)
1283 self.duration = None
1284 self.modifications = []
1286 def add_modification (self, mod):
1287 self.modifications.append (mod)
1288 def ly_expression (self):
1291 value = self.root.ly_expression ()
1293 value += self.duration.ly_expression ()
1297 # First print all additions/changes, and only afterwards all subtractions
1298 for m in self.modifications:
1300 value += m.ly_expression ()
1301 for m in self.modifications:
1303 value += m.ly_expression ()
1305 value += "/+%s" % self.bass.ly_expression ()
1309 class TremoloEvent (ArticulationEvent):
1310 def __init__ (self):
1311 Event.__init__ (self)
1314 def ly_expression (self):
1316 if self.bars and self.bars > 0:
1317 str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
1320 class BendEvent (ArticulationEvent):
1321 def __init__ (self):
1322 Event.__init__ (self)
1324 def ly_expression (self):
1325 if self.alter != None:
1326 return "-\\bendAfter #%s" % self.alter
1330 class RhythmicEvent(Event):
1331 def __init__ (self):
1332 Event.__init__ (self)
1333 self.duration = Duration()
1334 self.associated_events = []
1336 def add_associated_event (self, ev):
1338 self.associated_events.append (ev)
1340 def pre_chord_ly (self):
1341 return [ev.pre_chord_ly () for ev in self.associated_events]
1343 def pre_note_ly (self, is_chord_element):
1344 return [ev.pre_note_ly (is_chord_element) for ev in self.associated_events]
1346 def ly_expression_pre_note (self, is_chord_element):
1347 res = string.join (self.pre_note_ly (is_chord_element), ' ')
1352 def get_length (self):
1353 return self.duration.get_length()
1355 def get_properties (self):
1356 return ("'duration %s"
1357 % self.duration.lisp_expression ())
1359 class RestEvent (RhythmicEvent):
1360 def __init__ (self):
1361 RhythmicEvent.__init__ (self)
1364 def ly_expression (self):
1365 res = self.ly_expression_pre_note (False)
1367 return res + "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
1369 return 'r%s' % self.duration.ly_expression ()
1371 def print_ly (self, printer):
1372 for ev in self.associated_events:
1373 ev.print_ly (printer)
1375 self.pitch.print_ly (printer)
1376 self.duration.print_ly (printer)
1380 self.duration.print_ly (printer)
1382 class SkipEvent (RhythmicEvent):
1383 def ly_expression (self):
1384 return 's%s' % self.duration.ly_expression ()
1386 class NoteEvent(RhythmicEvent):
1387 def __init__ (self):
1388 RhythmicEvent.__init__ (self)
1390 self.drum_type = None
1391 self.cautionary = False
1392 self.forced_accidental = False
1394 def get_properties (self):
1395 str = RhythmicEvent.get_properties (self)
1398 str += self.pitch.lisp_expression ()
1399 elif self.drum_type:
1400 str += "'drum-type '%s" % self.drum_type
1404 def pitch_mods (self):
1407 excl_question += '?'
1408 if self.forced_accidental:
1409 excl_question += '!'
1411 return excl_question
1413 def ly_expression (self):
1414 # obtain all stuff that needs to be printed before the note:
1415 res = self.ly_expression_pre_note (True)
1417 return res + '%s%s%s' % (self.pitch.ly_expression (),
1419 self.duration.ly_expression ())
1420 elif self.drum_type:
1421 return res + '%s%s' (self.drum_type,
1422 self.duration.ly_expression ())
1424 def chord_element_ly (self):
1425 # obtain all stuff that needs to be printed before the note:
1426 res = self.ly_expression_pre_note (True)
1428 return res + '%s%s' % (self.pitch.ly_expression (),
1430 elif self.drum_type:
1431 return res + '%s%s' (self.drum_type)
1434 def print_ly (self, printer):
1435 for ev in self.associated_events:
1436 ev.print_ly (printer)
1438 self.pitch.print_ly (printer)
1439 printer (self.pitch_mods ())
1441 printer (self.drum_type)
1443 self.duration.print_ly (printer)
1445 class KeySignatureChange (Music):
1446 def __init__ (self):
1447 Music.__init__ (self)
1450 self.non_standard_alterations = None
1452 def format_non_standard_alteration (self, a):
1453 alter_dict = { -2: ",DOUBLE-FLAT",
1454 -1.5: ",THREE-Q-FLAT",
1460 1.5: ",THREE-Q-SHARP",
1463 accidental = alter_dict[a[1]]
1465 ly.warning (_ ("Unable to convert alteration %s to a lilypond expression") % a[1])
1468 return "( %s . %s )" % (a[0], accidental)
1470 return "(( %s . %s ) . %s )" % (a[2], a[0], accidental)
1474 def ly_expression (self):
1476 return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
1478 elif self.non_standard_alterations:
1479 alterations = [self.format_non_standard_alteration (a) for
1480 a in self.non_standard_alterations]
1481 return "\\set Staff.keySignature = #`(%s)" % string.join (alterations, " ")
1485 class TimeSignatureChange (Music):
1486 def __init__ (self):
1487 Music.__init__ (self)
1488 self.fractions = [4,4]
1490 def format_fraction (self, frac):
1491 if isinstance (frac, list):
1492 l = [self.format_fraction (f) for f in frac]
1493 return "(" + string.join (l, " ") + ")"
1497 def ly_expression (self):
1499 # Print out the style if we have ome, but the '() should only be
1500 # forced for 2/2 or 4/4, since in all other cases we'll get numeric
1501 # signatures anyway despite the default 'C signature style!
1502 is_common_signature = self.fractions in ([2,2], [4,4], [4,2])
1504 if self.style == "common":
1505 st = "\\defaultTimeSignature"
1506 elif (self.style != "'()"):
1507 st = "\\once \\override Staff.TimeSignature #'style = #%s " % self.style
1508 elif (self.style != "'()") or is_common_signature:
1509 st = "\\numericTimeSignature"
1511 # Easy case: self.fractions = [n,d] => normal \time n/d call:
1512 if len (self.fractions) == 2 and isinstance (self.fractions[0], int):
1513 return st + '\\time %d/%d ' % tuple (self.fractions)
1514 elif self.fractions:
1515 return st + "\\compoundMeter #'%s" % self.format_fraction (self.fractions)
1519 class ClefChange (Music):
1520 def __init__ (self):
1521 Music.__init__ (self)
1526 def octave_modifier (self):
1527 return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
1528 def clef_name (self):
1529 return {('G', 2): "treble",
1531 ('C', 1): "soprano",
1532 ('C', 2): "mezzosoprano",
1535 ('C', 5): "baritone",
1536 ('F', 3): "varbaritone",
1538 ('F', 5): "subbass",
1539 ("percussion", 2): "percussion",
1540 # Workaround: MuseScore uses PERC instead of percussion
1541 ("PERC", 2): "percussion",
1542 ("TAB", 5): "tab"}.get ((self.type, self.position), None)
1543 def ly_expression (self):
1544 return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
1547 "G": ("clefs.G", -2, -6),
1548 "C": ("clefs.C", 0, 0),
1549 "F": ("clefs.F", 2, 6),
1552 def lisp_expression (self):
1554 (glyph, pos, c0) = self.clef_dict[self.type]
1558 (make-music 'SequentialMusic
1561 (make-property-set 'clefGlyph "%s") 'Staff)
1563 (make-property-set 'clefPosition %d) 'Staff)
1565 (make-property-set 'middleCPosition %d) 'Staff)))
1566 """ % (glyph, pos, c0)
1569 class Transposition (Music):
1570 def __init__ (self):
1571 Music.__init__ (self)
1573 def ly_expression (self):
1574 self.pitch._force_absolute_pitch = True
1575 return '\\transposition %s' % self.pitch.ly_expression ()
1577 class StaffChange (Music):
1578 def __init__ (self, staff):
1579 Music.__init__ (self)
1581 def ly_expression (self):
1583 return "\\change Staff=\"%s\"" % self.staff
1587 class SetEvent (Music):
1588 def __init__ (self, contextprop, value):
1589 Music.__init__ (self)
1590 self.context_prop = contextprop
1592 def ly_expression (self):
1594 return "\\set %s = %s" % (self.context_prop, self.value)
1598 class StaffLinesEvent (Music):
1599 def __init__ (self, lines):
1600 Music.__init__ (self)
1602 def ly_expression (self):
1603 if (self.lines > 0):
1604 return "\\stopStaff \\override Staff.StaffSymbol #'line-count = #%s \\startStaff" % self.lines
1606 return "\\stopStaff \\revert Staff.StaffSymbol #'line-count \\startStaff"
1608 class TempoMark (Music):
1609 def __init__ (self):
1610 Music.__init__ (self)
1611 self.baseduration = None
1612 self.newduration = None
1614 self.parentheses = False
1615 def set_base_duration (self, dur):
1616 self.baseduration = dur
1617 def set_new_duration (self, dur):
1618 self.newduration = dur
1619 def set_beats_per_minute (self, beats):
1621 def set_parentheses (self, parentheses):
1622 self.parentheses = parentheses
1623 def wait_for_note (self):
1625 def duration_to_markup (self, dur):
1627 # Generate the markup to print the note, use scheme mode for
1628 # ly_expression to get longa and not \longa (which causes an error)
1629 return "\\general-align #Y #DOWN \\smaller \\note #\"%s\" #UP" % dur.ly_expression(None, True)
1632 def tempo_markup_template (self):
1633 return "\\mark\\markup { \\fontsize #-2 \\line { %s } }"
1634 def ly_expression (self):
1636 if not self.baseduration:
1639 if self.parentheses:
1640 res += "\\tempo \"\" %s=%s" % (self.baseduration.ly_expression(), self.beats)
1642 res += "\\tempo %s=%s" % (self.baseduration.ly_expression(), self.beats)
1643 elif self.newduration:
1644 dm = self.duration_to_markup (self.baseduration)
1645 ndm = self.duration_to_markup (self.newduration)
1646 if self.parentheses:
1647 contents = "\"(\" %s = %s \")\"" % (dm, ndm)
1649 contents = " %s = %s " % (dm, ndm)
1650 res += self.tempo_markup_template() % contents
1655 class FiguredBassNote (Music):
1656 def __init__ (self):
1657 Music.__init__ (self)
1661 def set_prefix (self, prefix):
1662 self.prefix = prefix
1663 def set_suffix (self, suffix):
1664 self.prefix = suffix
1665 def set_number (self, number):
1666 self.number = number
1667 def ly_expression (self):
1680 class FiguredBassEvent (NestedMusic):
1681 def __init__ (self):
1682 NestedMusic.__init__ (self)
1683 self.duration = None
1684 self.real_duration = 0
1685 self.parentheses = False
1687 def set_duration (self, dur):
1689 def set_parentheses (self, par):
1690 self.parentheses = par
1691 def set_real_duration (self, dur):
1692 self.real_duration = dur
1694 def print_ly (self, printer):
1695 figured_bass_events = [e for e in self.elements if
1696 isinstance (e, FiguredBassNote)]
1697 if figured_bass_events:
1699 for x in figured_bass_events:
1700 notes.append (x.ly_expression ())
1701 contents = string.join (notes)
1702 if self.parentheses:
1703 contents = '[%s]' % contents
1704 printer ('<%s>' % contents)
1705 self.duration.print_ly (printer)
1708 class MultiMeasureRest(Music):
1710 def lisp_expression (self):
1713 'MultiMeasureRestMusicGroup
1715 (list (make-music (quote BarCheck))
1720 'MultiMeasureRestEvent
1723 (make-music (quote BarCheck))))
1724 """ % self.duration.lisp_expression ()
1726 def ly_expression (self):
1727 return 'R%s' % self.duration.ly_expression ()
1730 class Break (Music):
1731 def __init__ (self, tp="break"):
1732 Music.__init__ (self)
1734 def print_ly (self, printer):
1736 printer.dump ("\\%s" % self.type)
1739 def __init__ (self, command = "StaffGroup"):
1740 self.stafftype = command
1742 self.instrument_name = None
1743 self.short_instrument_name = None
1747 self.is_group = True
1748 self.context_modifications = []
1749 # part_information is a list with entries of the form
1750 # [staffid, voicelist]
1751 # where voicelist is a list with entries of the form
1752 # [voiceid1, [lyricsid11, lyricsid12,...] ]
1753 self.part_information = None
1755 def append_staff (self, staff):
1756 self.children.append (staff)
1758 def set_part_information (self, part_name, staves_info):
1759 if part_name == self.id:
1760 self.part_information = staves_info
1762 for c in self.children:
1763 c.set_part_information (part_name, staves_info)
1765 def add_context_modification (self, modification):
1766 self.context_modifications.append (modification)
1768 def print_ly_contents (self, printer):
1769 for c in self.children:
1771 c.print_ly (printer)
1772 def needs_with (self):
1774 needs_with |= self.spanbar == "no"
1775 needs_with |= self.instrument_name != None
1776 needs_with |= self.short_instrument_name != None
1777 needs_with |= (self.symbol != None) and (self.symbol != "bracket")
1779 def print_ly_context_mods (self, printer):
1780 if self.instrument_name or self.short_instrument_name:
1781 printer.dump ("\\consists \"Instrument_name_engraver\"")
1782 if self.spanbar == "no":
1783 printer.dump ("\\override SpanBar #'transparent = ##t")
1784 brack = {"brace": "SystemStartBrace",
1786 "line": "SystemStartSquare"}.get (self.symbol, None)
1788 printer.dump ("systemStartDelimiter = #'%s" % brack)
1790 def print_ly_overrides (self, printer):
1791 needs_with = self.needs_with () | (len (self.context_modifications) > 0);
1793 printer.dump ("\\with {")
1794 self.print_ly_context_mods (printer)
1795 for m in self.context_modifications:
1799 def print_ly (self, printer):
1801 printer.dump ("\\new %s" % self.stafftype)
1802 self.print_ly_overrides (printer)
1805 if self.stafftype and self.instrument_name:
1806 printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
1807 escape_instrument_string (self.instrument_name)))
1809 if self.stafftype and self.short_instrument_name:
1810 printer.dump ("\\set %s.shortInstrumentName = %s" % (self.stafftype,
1811 escape_instrument_string (self.short_instrument_name)))
1813 self.print_ly_contents (printer)
1819 class Staff (StaffGroup):
1820 def __init__ (self, command = "Staff"):
1821 StaffGroup.__init__ (self, command)
1822 self.is_group = False
1824 self.voice_command = "Voice"
1825 self.substafftype = None
1827 def needs_with (self):
1829 def print_ly_context_mods (self, printer):
1832 def print_ly_contents (self, printer):
1833 if not self.id or not self.part_information:
1835 sub_staff_type = self.substafftype
1836 if not sub_staff_type:
1837 sub_staff_type = self.stafftype
1839 for [staff_id, voices] in self.part_information:
1840 # Chord names need to come before the staff itself!
1841 for [v, lyrics, figuredbass, chordnames] in voices:
1843 printer ('\context ChordNames = "%s" \\%s' % (chordnames, chordnames))
1845 # now comes the real staff definition:
1847 printer ('\\context %s = "%s" << ' % (sub_staff_type, staff_id))
1849 printer ('\\context %s << ' % sub_staff_type)
1852 nr_voices = len (voices)
1853 for [v, lyrics, figuredbass, chordnames] in voices:
1855 voice_count_text = ''
1857 voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo',
1858 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
1859 printer ('\\context %s = "%s" {%s \\%s }' % (self.voice_command, v, voice_count_text, v))
1863 printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
1866 printer ('\context FiguredBass = "%s" \\%s' % (figuredbass, figuredbass))
1869 def print_ly (self, printer):
1870 if self.part_information and len (self.part_information) > 1:
1871 self.stafftype = "PianoStaff"
1872 self.substafftype = "Staff"
1873 StaffGroup.print_ly (self, printer)
1875 class TabStaff (Staff):
1876 def __init__ (self, command = "TabStaff"):
1877 Staff.__init__ (self, command)
1878 self.string_tunings = []
1879 self.tablature_format = None
1880 self.voice_command = "TabVoice"
1881 def print_ly_overrides (self, printer):
1882 if self.string_tunings or self.tablature_format:
1883 printer.dump ("\\with {")
1884 if self.string_tunings:
1885 printer.dump ("stringTunings = #`(")
1886 for i in self.string_tunings:
1887 printer.dump (",%s" % i.lisp_expression ())
1889 if self.tablature_format:
1890 printer.dump ("tablatureFormat = #%s" % self.tablature_format)
1894 class DrumStaff (Staff):
1895 def __init__ (self, command = "DrumStaff"):
1896 Staff.__init__ (self, command)
1897 self.drum_style_table = None
1898 self.voice_command = "DrumVoice"
1899 def print_ly_overrides (self, printer):
1900 if self.drum_style_table:
1901 printer.dump ("\with {")
1902 printer.dump ("drumStyleTable = #%s" % self.drum_style_table)
1905 class RhythmicStaff (Staff):
1906 def __init__ (self, command = "RhythmicStaff"):
1907 Staff.__init__ (self, command)
1910 def __init__ (self):
1911 self.contents = None
1912 self.create_midi = False
1914 def set_contents (self, contents):
1915 self.contents = contents
1917 def set_part_information (self, part_id, staves_info):
1919 self.contents.set_part_information (part_id, staves_info)
1921 def print_ly (self, printer):
1922 printer.dump ("\\score {");
1925 self.contents.print_ly (printer);
1926 printer.dump ("\\layout {}");
1928 if not self.create_midi:
1929 printer.dump ("% To create MIDI output, uncomment the following line:");
1931 printer.dump ("% ");
1932 printer.dump ("\\midi {}");
1940 bflat.alteration = -1
1950 print bflat.semitones()
1951 print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
1952 print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
1954 print bflat.semitones(), 'down'
1955 print bflat.transposed (down)
1956 print bflat.transposed (down).transposed (down)
1957 print bflat.transposed (down).transposed (down).transposed (down)
1961 def test_printer ():
1969 m = SequentialMusic()
1970 m.append (make_note ())
1971 m.append (make_note ())
1972 m.append (make_note ())
1975 t = TimeScaledMusic ()
1981 m = SequentialMusic ()
1982 m.append (make_tup ())
1983 m.append (make_tup ())
1984 m.append (make_tup ())
1986 printer = Output_printer()
1987 m.print_ly (printer)
1991 m = SequentialMusic()
1995 n.duration.duration_log = l
1997 evc.insert_around (None, n, 0)
1998 m.insert_around (None, evc, 0)
2002 n.duration.duration_log = l
2004 evc.insert_around (None, n, 0)
2005 m.insert_around (None, evc, 0)
2009 n.duration.duration_log = l
2011 evc.insert_around (None, n, 0)
2012 m.insert_around (None, evc, 0)
2016 m.insert_around (None, evc, 0)
2021 tonic.alteration = -2
2022 n = KeySignatureChange()
2023 n.tonic=tonic.copy()
2024 n.scale = [0, 0, -2, 0, 0,-2,-2]
2026 evc.insert_around (None, n, 0)
2027 m.insert_around (None, evc, 0)
2032 if __name__ == '__main__':
2038 expr.set_start (Rational (0))
2039 print expr.ly_expression()
2040 start = Rational (0,4)
2041 stop = Rational (4,2)
2042 def sub(x, start=start, stop=stop):
2043 ok = x.start >= start and x.start +x.get_length() <= stop
2046 print expr.lisp_sub_expression(sub)