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 { \\center-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
201 # implement the midi command line option '-m' and '--midi'
202 # if TRUE add midi-block to .ly file (see below)
203 def set_create_midi (option):
207 def get_create_midi ():
213 # Implement the different note names for the various languages
214 def pitch_generic (pitch, notenames, accidentals):
215 str = notenames[pitch.step]
216 halftones = int (pitch.alteration)
218 str += accidentals[0] * (-halftones)
219 elif pitch.alteration > 0:
220 str += accidentals[3] * (halftones)
221 # Handle remaining fraction to pitch.alteration (for microtones)
222 if (halftones != pitch.alteration):
223 if None in accidentals[1:3]:
224 ly.warning (_ ("Language does not support microtones contained in the piece"))
227 str += {-0.5: accidentals[1], 0.5: accidentals[2]}[pitch.alteration-halftones]
229 ly.warning (_ ("Language does not support microtones contained in the piece"))
232 def pitch_general (pitch):
233 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['es', 'eh', 'ih', 'is'])
234 return str.replace ('aes', 'as').replace ('ees', 'es')
236 def pitch_nederlands (pitch):
237 return pitch_general (pitch)
239 def pitch_english (pitch):
240 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'b'], ['f', 'qf', 'qs', 's'])
241 return str.replace ('aes', 'as').replace ('ees', 'es')
243 def pitch_deutsch (pitch):
244 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['es', 'eh', 'ih', 'is'])
245 return str.replace ('hes', 'b').replace ('aes', 'as').replace ('ees', 'es')
247 def pitch_norsk (pitch):
248 return pitch_deutsch (pitch)
250 def pitch_svenska (pitch):
251 str = pitch_generic (pitch, ['c', 'd', 'e', 'f', 'g', 'a', 'h'], ['ess', None, None, 'iss'])
252 return str.replace ('hess', 'b').replace ('aes', 'as').replace ('ees', 'es')
254 def pitch_italiano (pitch):
255 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', 'sb', 'sd', 'd'])
258 def pitch_catalan (pitch):
259 return pitch_italiano (pitch)
261 def pitch_espanol (pitch):
262 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 's'])
265 def pitch_vlaams (pitch):
266 str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 'k'])
269 def set_pitch_language (language):
270 global pitch_generating_function
272 "nederlands": pitch_nederlands,
273 "english": pitch_english,
274 "deutsch": pitch_deutsch,
275 "norsk": pitch_norsk,
276 "svenska": pitch_svenska,
277 "italiano": pitch_italiano,
278 "catalan": pitch_catalan,
279 "espanol": pitch_espanol,
280 "vlaams": pitch_vlaams}
281 pitch_generating_function = function_dict.get (language, pitch_general)
283 # global variable to hold the formatting function.
284 pitch_generating_function = pitch_general
292 self._force_absolute_pitch = False
295 return self.ly_expression()
297 def transposed (self, interval):
299 c.alteration += interval.alteration
300 c.step += interval.step
301 c.octave += interval.octave
304 target_st = self.semitones() + interval.semitones()
305 c.alteration += target_st - c.semitones()
312 c.octave += c.step / 7
315 def lisp_expression (self):
316 return '(ly:make-pitch %d %d %d)' % (self.octave,
322 p.alteration = self.alteration
324 p.octave = self.octave
328 return self.step + self.octave *7
330 def semitones (self):
331 return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
333 def ly_step_expression (self):
334 return pitch_generating_function (self)
336 def absolute_pitch (self):
338 return "'" * (self.octave + 1)
339 elif self.octave < -1:
340 return "," * (-self.octave - 1)
344 def relative_pitch (self):
345 global previous_pitch
346 if not previous_pitch:
347 previous_pitch = self
348 return self.absolute_pitch ()
349 previous_pitch_steps = previous_pitch.octave * 7 + previous_pitch.step
350 this_pitch_steps = self.octave * 7 + self.step
351 pitch_diff = (this_pitch_steps - previous_pitch_steps)
352 previous_pitch = self
354 return "'" * ((pitch_diff + 3) / 7)
355 elif pitch_diff < -3:
356 return "," * ((-pitch_diff + 3) / 7)
360 def ly_expression (self):
361 str = self.ly_step_expression ()
362 if relative_pitches and not self._force_absolute_pitch:
363 str += self.relative_pitch ()
365 str += self.absolute_pitch ()
369 def print_ly (self, outputter):
370 outputter (self.ly_expression())
375 self.start = Rational (0)
377 self.identifier = None
379 def get_length(self):
382 def get_properties (self):
385 def has_children (self):
388 def get_index (self):
390 return self.parent.elements.index (self)
394 return self.__class__.__name__
396 def lisp_expression (self):
399 props = self.get_properties ()
401 return "(make-music '%s %s)" % (name, props)
403 def set_start (self, start):
406 def find_first (self, predicate):
411 def print_comment (self, printer, text = None):
422 lines = string.split (text, '\n')
425 printer.unformatted_output ('% ' + l)
429 def print_with_identifier (self, printer):
431 printer ("\\%s" % self.identifier)
433 self.print_ly (printer)
435 def print_ly (self, printer):
436 printer (self.ly_expression ())
438 class MusicWrapper (Music):
442 def print_ly (self, func):
443 self.element.print_ly (func)
445 class ModeChangingMusicWrapper (MusicWrapper):
447 MusicWrapper.__init__ (self)
448 self.mode = 'notemode'
450 def print_ly (self, func):
451 func ('\\%s' % self.mode)
452 MusicWrapper.print_ly (self, func)
454 class RelativeMusic (MusicWrapper):
456 MusicWrapper.__init__ (self)
457 self.basepitch = None
459 def print_ly (self, func):
460 global previous_pitch
461 global relative_pitches
462 prev_relative_pitches = relative_pitches
463 relative_pitches = True
464 previous_pitch = self.basepitch
465 if not previous_pitch:
466 previous_pitch = Pitch ()
467 func ('\\relative %s%s' % (pitch_generating_function (previous_pitch),
468 previous_pitch.absolute_pitch ()))
469 MusicWrapper.print_ly (self, func)
470 relative_pitches = prev_relative_pitches
472 class TimeScaledMusic (MusicWrapper):
474 MusicWrapper.__init__ (self)
477 self.display_number = "actual" # valid values "actual" | "both" | None
478 # Display the basic note length for the tuplet:
479 self.display_type = None # value values "actual" | "both" | None
480 self.display_bracket = "bracket" # valid values "bracket" | "curved" | None
481 self.actual_type = None # The actually played unit of the scaling
482 self.normal_type = None # The basic unit of the scaling
483 self.display_numerator = None
484 self.display_denominator = None
486 def print_ly (self, func):
487 if self.display_bracket == None:
488 func ("\\once \\override TupletBracket #'stencil = ##f")
490 elif self.display_bracket == "curved":
491 ly.warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
492 func ("\\once \\override TupletBracket #'stencil = #ly:slur::print")
495 base_number_function = {None: "#f",
496 "actual": "tuplet-number::calc-denominator-text",
497 "both": "tuplet-number::calc-fraction-text"}.get (self.display_number, None)
498 # If we have non-standard numerator/denominator, use our custom function
499 if self.display_number == "actual" and self.display_denominator:
500 base_number_function = "(tuplet-number::non-default-tuplet-denominator-text %s)" % self.display_denominator
501 elif self.display_number == "both" and (self.display_denominator or self.display_numerator):
502 if self.display_numerator:
503 num = self.display_numerator
506 if self.display_denominator:
507 den = self.display_denominator
510 base_number_function = "(tuplet-number::non-default-tuplet-fraction-text %s %s)" % (den, num)
513 if self.display_type == "actual" and self.normal_type:
514 # Obtain the note duration in scheme-mode, i.e. \longa as \\longa
515 base_duration = self.normal_type.ly_expression (None, True)
516 func ("\\once \\override TupletNumber #'text = #(tuplet-number::append-note-wrapper %s \"%s\")" %
517 (base_number_function, base_duration))
519 elif self.display_type == "both": # TODO: Implement this using actual_type and normal_type!
520 if self.display_number == None:
521 func ("\\once \\override TupletNumber #'stencil = ##f")
523 elif self.display_number == "both":
524 den_duration = self.normal_type.ly_expression (None, True)
525 # If we don't have an actual type set, use the normal duration!
527 num_duration = self.actual_type.ly_expression (None, True)
529 num_duration = den_duration
530 if (self.display_denominator or self.display_numerator):
531 func ("\\once \\override TupletNumber #'text = #(tuplet-number::non-default-fraction-with-notes %s \"%s\" %s \"%s\")" %
532 (self.display_denominator, den_duration,
533 self.display_numerator, num_duration))
536 func ("\\once \\override TupletNumber #'text = #(tuplet-number::fraction-with-notes \"%s\" \"%s\")" %
537 (den_duration, num_duration))
540 if self.display_number == None:
541 func ("\\once \\override TupletNumber #'stencil = ##f")
543 elif self.display_number == "both":
544 func ("\\once \\override TupletNumber #'text = #%s" % base_number_function)
547 func ('\\times %d/%d ' %
548 (self.numerator, self.denominator))
549 func.add_factor (Rational (self.numerator, self.denominator))
550 MusicWrapper.print_ly (self, func)
553 class NestedMusic(Music):
555 Music.__init__ (self)
558 def append (self, what):
560 self.elements.append (what)
562 def has_children (self):
565 def insert_around (self, succ, elt, dir):
566 assert elt.parent == None
567 assert succ == None or succ in self.elements
572 idx = self.elements.index (succ)
579 idx = len (self.elements)
581 self.elements.insert (idx, elt)
584 def get_properties (self):
585 return ("'elements (list %s)"
586 % string.join (map (lambda x: x.lisp_expression(),
589 def get_subset_properties (self, predicate):
590 return ("'elements (list %s)"
591 % string.join (map (lambda x: x.lisp_expression(),
592 filter ( predicate, self.elements))))
593 def get_neighbor (self, music, dir):
594 assert music.parent == self
595 idx = self.elements.index (music)
597 idx = min (idx, len (self.elements) -1)
600 return self.elements[idx]
602 def delete_element (self, element):
603 assert element in self.elements
605 self.elements.remove (element)
606 element.parent = None
608 def set_start (self, start):
610 for e in self.elements:
613 def find_first (self, predicate):
614 r = Music.find_first (self, predicate)
618 for e in self.elements:
619 r = e.find_first (predicate)
624 class SequentialMusic (NestedMusic):
625 def get_last_event_chord (self):
627 at = len( self.elements ) - 1
629 not isinstance (self.elements[at], ChordEvent) and
630 not isinstance (self.elements[at], BarLine)):
633 if (at >= 0 and isinstance (self.elements[at], ChordEvent)):
634 value = self.elements[at]
637 def print_ly (self, printer, newline = True):
640 self.print_comment (printer)
644 for e in self.elements:
651 def lisp_sub_expression (self, pred):
655 props = self.get_subset_properties (pred)
657 return "(make-music '%s %s)" % (name, props)
659 def set_start (self, start):
660 for e in self.elements:
662 start += e.get_length()
666 self.repeat_type = "volta"
667 self.repeat_count = 2
670 def set_music (self, music):
671 if isinstance (music, Music):
673 elif isinstance (music, list):
674 self.music = SequentialMusic ()
675 self.music.elements = music
677 ly.warning (_ ("unable to set the music %(music)s for the repeat %(repeat)s") % \
678 {'music':music, 'repeat':self})
679 def add_ending (self, music):
680 self.endings.append (music)
681 def print_ly (self, printer):
682 printer.dump ('\\repeat %s %s' % (self.repeat_type, self.repeat_count))
684 self.music.print_ly (printer)
686 ly.warning (_ ("encountered repeat without body"))
689 printer.dump ('\\alternative {')
690 for e in self.endings:
697 self.lyrics_syllables = []
699 def print_ly (self, printer):
700 printer.dump ("\lyricmode {")
701 for l in self.lyrics_syllables:
702 printer.dump ( "%s " % l )
705 def ly_expression (self):
706 lstr = "\lyricmode {\n "
707 for l in self.lyrics_syllables:
715 self.header_fields = {}
716 def set_field (self, field, value):
717 self.header_fields[field] = value
719 def print_ly (self, printer):
720 printer.dump ("\header {")
722 for (k,v) in self.header_fields.items ():
724 printer.dump ('%s = %s' % (k,v))
733 self.global_staff_size = -1
736 self.page_height = -1
739 self.bottom_margin = -1
740 self.left_margin = -1
741 self.right_margin = -1
742 self.system_left_margin = -1
743 self.system_right_margin = -1
744 self.system_distance = -1
745 self.top_system_distance = -1
747 def print_length_field (self, printer, field, value):
749 printer.dump ("%s = %s\\cm" % (field, value))
751 def print_ly (self, printer):
752 if self.global_staff_size > 0:
753 printer.dump ('#(set-global-staff-size %s)' % self.global_staff_size)
755 printer.dump ('\\paper {')
757 self.print_length_field (printer, "paper-width", self.page_width)
758 self.print_length_field (printer, "paper-height", self.page_height)
759 self.print_length_field (printer, "top-margin", self.top_margin)
760 self.print_length_field (printer, "bottom-margin", self.bottom_margin)
761 self.print_length_field (printer, "left-margin", self.left_margin)
762 # TODO: maybe set line-width instead of right-margin?
763 self.print_length_field (printer, "right-margin", self.right_margin)
764 # TODO: What's the corresponding setting for system_left_margin and
765 # system_right_margin in LilyPond?
766 self.print_length_field (printer, "between-system-space", self.system_distance)
767 self.print_length_field (printer, "page-top-space", self.top_system_distance)
774 self.context_dict = {}
775 def add_context (self, context):
776 if not self.context_dict.has_key (context):
777 self.context_dict[context] = []
778 def set_context_item (self, context, item):
779 self.add_context (context)
780 if not item in self.context_dict[context]:
781 self.context_dict[context].append (item)
782 def print_ly (self, printer):
783 if self.context_dict.items ():
784 printer.dump ('\\layout {')
786 for (context, defs) in self.context_dict.items ():
787 printer.dump ('\\context { \\%s' % context)
798 class ChordEvent (NestedMusic):
800 NestedMusic.__init__ (self)
801 self.after_grace_elements = None
802 self.grace_elements = None
803 self.grace_type = None
804 def append_grace (self, element):
806 if not self.grace_elements:
807 self.grace_elements = SequentialMusic ()
808 self.grace_elements.append (element)
809 def append_after_grace (self, element):
811 if not self.after_grace_elements:
812 self.after_grace_elements = SequentialMusic ()
813 self.after_grace_elements.append (element)
815 def has_elements (self):
816 return [e for e in self.elements if
817 isinstance (e, NoteEvent) or isinstance (e, RestEvent)] != []
820 def get_length (self):
822 for e in self.elements:
823 l = max(l, e.get_length())
826 def get_duration (self):
827 note_events = [e for e in self.elements if
828 isinstance (e, NoteEvent) or isinstance (e, RestEvent)]
830 return note_events[0].duration
834 def print_ly (self, printer):
835 note_events = [e for e in self.elements if
836 isinstance (e, NoteEvent)]
838 rest_events = [e for e in self.elements if
839 isinstance (e, RhythmicEvent)
840 and not isinstance (e, NoteEvent)]
842 other_events = [e for e in self.elements if
843 not isinstance (e, RhythmicEvent)]
845 if self.after_grace_elements:
846 printer ('\\afterGrace {')
848 if self.grace_elements and self.elements:
850 printer ('\\%s' % self.grace_type)
853 # don't print newlines after the { and } braces
854 self.grace_elements.print_ly (printer, False)
855 elif self.grace_elements: # no self.elements!
856 ly.warning (_ ("Grace note with no following music: %s") % self.grace_elements)
858 printer ('\\%s' % self.grace_type)
861 self.grace_elements.print_ly (printer, False)
864 # Print all overrides and other settings needed by the
865 # articulations/ornaments before the note
866 for e in other_events:
867 e.print_before_note (printer)
870 rest_events[0].print_ly (printer)
871 elif len (note_events) == 1:
872 note_events[0].print_ly (printer)
874 global previous_pitch
877 for x in note_events:
878 pitches.append (x.chord_element_ly ())
880 basepitch = previous_pitch
881 printer ('<%s>' % string.join (pitches))
882 previous_pitch = basepitch
883 duration = self.get_duration ()
885 duration.print_ly (printer)
889 for e in other_events:
892 for e in other_events:
893 e.print_after_note (printer)
895 if self.after_grace_elements:
897 self.after_grace_elements.print_ly (printer, False)
899 self.print_comment (printer)
901 class Partial (Music):
903 Music.__init__ (self)
905 def print_ly (self, printer):
907 printer.dump ("\\partial %s" % self.partial.ly_expression ())
909 class BarLine (Music):
911 Music.__init__ (self)
915 def print_ly (self, printer):
916 bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': "dashed",
917 'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
918 'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'",
919 'short': "'", 'none': "" }.get (self.type, None)
920 if bar_symbol <> None:
921 printer.dump ('\\bar "%s"' % bar_symbol)
925 if self.bar_number > 0 and (self.bar_number % 10) == 0:
926 printer.dump ("\\barNumberCheck #%d " % self.bar_number)
927 elif self.bar_number > 0:
928 printer.print_verbatim (' %% %d' % self.bar_number)
931 def ly_expression (self):
936 # strings to print before the note to which an event is attached.
937 # Ignored for notes etc.
938 self.before_note = None
939 self.after_note = None
940 # print something before the note to which an event is attached, e.g. overrides
941 def print_before_note (self, printer):
943 printer.dump (self.before_note)
944 # print something after the note to which an event is attached, e.g. resetting
945 def print_after_note (self, printer):
947 printer.dump (self.after_note)
950 class SpanEvent (Event):
952 Event.__init__ (self)
953 self.span_direction = 0 # start/stop
954 self.line_type = 'solid'
955 self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
956 self.size = 0 # size of e.g. ocrave shift
957 def wait_for_note (self):
959 def get_properties(self):
960 return "'span-direction %d" % self.span_direction
961 def set_span_type (self, type):
962 self.span_type = type
964 class SlurEvent (SpanEvent):
965 def print_before_note (self, printer):
966 command = {'dotted': '\\slurDotted',
967 'dashed' : '\\slurDashed'}.get (self.line_type, '')
968 if command and self.span_direction == -1:
969 printer.dump (command)
970 def print_after_note (self, printer):
971 # reset non-solid slur types!
972 command = {'dotted': '\\slurSolid',
973 'dashed' : '\\slurSolid'}.get (self.line_type, '')
974 if command and self.span_direction == -1:
975 printer.dump (command)
976 def ly_expression (self):
977 return {-1: '(', 1:')'}.get (self.span_direction, '')
979 class BeamEvent (SpanEvent):
980 def ly_expression (self):
981 return {-1: '[', 1:']'}.get (self.span_direction, '')
983 class PedalEvent (SpanEvent):
984 def ly_expression (self):
985 return {-1: '\\sustainOn',
986 0:'\\sustainOff\\sustainOn',
987 1:'\\sustainOff'}.get (self.span_direction, '')
989 class TextSpannerEvent (SpanEvent):
990 def ly_expression (self):
991 return {-1: '\\startTextSpan',
992 1:'\\stopTextSpan'}.get (self.span_direction, '')
994 class BracketSpannerEvent (SpanEvent):
995 # Ligature brackets use prefix-notation!!!
996 def print_before_note (self, printer):
997 if self.span_direction == -1:
999 # the bracket after the last note
1000 def print_after_note (self, printer):
1001 if self.span_direction == 1:
1003 # we're printing everything in print_(before|after)_note...
1004 def ly_expression (self):
1008 class OctaveShiftEvent (SpanEvent):
1009 def wait_for_note (self):
1011 def set_span_type (self, type):
1012 self.span_type = {'up': 1, 'down': -1}.get (type, 0)
1013 def ly_octave_shift_indicator (self):
1014 # convert 8/15 to lilypond indicators (+-1/+-2)
1016 value = {8: 1, 15: 2}[self.size]
1018 ly.warning (_ ("Invalid octave shift size found: %s. Using no shift.") % self.size)
1020 # negative values go up!
1021 value *= -1*self.span_type
1023 def ly_expression (self):
1024 dir = self.ly_octave_shift_indicator ()
1027 value = '\ottava #%s' % dir
1030 1: '\ottava #0'}.get (self.span_direction, '')
1032 class TrillSpanEvent (SpanEvent):
1033 def ly_expression (self):
1034 return {-1: '\\startTrillSpan',
1035 0: '', # no need to write out anything for type='continue'
1036 1:'\\stopTrillSpan'}.get (self.span_direction, '')
1038 class GlissandoEvent (SpanEvent):
1039 def print_before_note (self, printer):
1040 if self.span_direction == -1:
1042 "dashed" : "dashed-line",
1043 "dotted" : "dotted-line",
1045 }. get (self.line_type, None)
1047 printer.dump ("\\once \\override Glissando #'style = #'%s" % style)
1048 def ly_expression (self):
1049 return {-1: '\\glissando',
1050 1:''}.get (self.span_direction, '')
1052 class ArpeggioEvent(Event):
1053 def __init__ (self):
1054 Event.__init__ (self)
1056 self.non_arpeggiate = False
1057 def wait_for_note (self):
1059 def print_before_note (self, printer):
1060 if self.non_arpeggiate:
1061 printer.dump ("\\arpeggioBracket")
1063 dir = { -1: "\\arpeggioArrowDown", 1: "\\arpeggioArrowUp" }.get (self.direction, '')
1066 def print_after_note (self, printer):
1067 if self.non_arpeggiate or self.direction:
1068 printer.dump ("\\arpeggioNormal")
1069 def ly_expression (self):
1070 return ('\\arpeggio')
1073 class TieEvent(Event):
1074 def ly_expression (self):
1078 class HairpinEvent (SpanEvent):
1079 def set_span_type (self, type):
1080 self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
1081 def hairpin_to_ly (self):
1082 if self.span_direction == 1:
1085 return {1: '\<', -1: '\>'}.get (self.span_type, '')
1087 def ly_expression (self):
1088 return self.hairpin_to_ly ()
1090 def print_ly (self, printer):
1091 val = self.hairpin_to_ly ()
1097 class DynamicsEvent (Event):
1098 def __init__ (self):
1099 Event.__init__ (self)
1101 def wait_for_note (self):
1103 def ly_expression (self):
1105 return '\%s' % self.type
1109 def print_ly (self, printer):
1111 printer.dump ("\\%s" % self.type)
1113 class MarkEvent (Event):
1114 def __init__ (self, text="\\default"):
1115 Event.__init__ (self)
1117 def wait_for_note (self):
1119 def ly_contents (self):
1121 return '%s' % self.mark
1124 def ly_expression (self):
1125 return '\\mark %s' % self.ly_contents ()
1127 class MusicGlyphMarkEvent (MarkEvent):
1128 def ly_contents (self):
1130 return '\\markup { \\musicglyph #"scripts.%s" }' % self.mark
1135 class TextEvent (Event):
1136 def __init__ (self):
1137 Event.__init__ (self)
1139 self.force_direction = None
1141 def wait_for_note (self):
1144 def direction_mod (self):
1145 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
1147 def ly_expression (self):
1148 base_string = '%s\"%s\"'
1150 base_string = '%s\markup{ ' + self.markup + ' {%s} }'
1151 return base_string % (self.direction_mod (), self.text)
1153 class ArticulationEvent (Event):
1154 def __init__ (self):
1155 Event.__init__ (self)
1157 self.force_direction = None
1158 def wait_for_note (self):
1161 def direction_mod (self):
1162 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '')
1164 def ly_expression (self):
1165 return '%s\\%s' % (self.direction_mod (), self.type)
1167 class ShortArticulationEvent (ArticulationEvent):
1168 def direction_mod (self):
1170 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
1171 def ly_expression (self):
1173 return '%s%s' % (self.direction_mod (), self.type)
1177 class NoDirectionArticulationEvent (ArticulationEvent):
1178 def ly_expression (self):
1180 return '\\%s' % self.type
1184 class MarkupEvent (ShortArticulationEvent):
1185 def __init__ (self):
1186 ArticulationEvent.__init__ (self)
1187 self.contents = None
1188 def ly_expression (self):
1190 return "%s\\markup { %s }" % (self.direction_mod (), self.contents)
1194 class FretEvent (MarkupEvent):
1195 def __init__ (self):
1196 MarkupEvent.__init__ (self)
1197 self.force_direction = 1
1202 def ly_expression (self):
1204 if self.strings <> 6:
1205 val += "w:%s;" % self.strings
1207 val += "h:%s;" % self.frets
1208 if self.barre and len (self.barre) >= 3:
1209 val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2])
1210 have_fingering = False
1211 for i in self.elements:
1213 val += "%s-%s" % (i[0], i[1])
1215 have_fingering = True
1221 return "%s\\markup { \\fret-diagram #\"%s\" }" % (self.direction_mod (), val)
1226 class FunctionWrapperEvent (Event):
1227 def __init__ (self, function_name = None):
1228 Event.__init__ (self)
1229 self.function_name = function_name
1230 def pre_note_ly (self, is_chord_element):
1231 if self.function_name:
1232 return "\\%s" % self.function_name
1235 def pre_chord_ly (self):
1237 def ly_expression (self):
1238 if self.function_name:
1239 return "\\%s" % self.function_name
1243 class ParenthesizeEvent (FunctionWrapperEvent):
1244 def __init__ (self):
1245 FunctionWrapperEvent.__init__ (self, "parenthesize")
1247 class NotestyleEvent (Event):
1248 def __init__ (self):
1249 Event.__init__ (self)
1252 def pre_chord_ly (self):
1254 return "\\once \\override NoteHead #'style = #%s" % self.style
1257 def pre_note_ly (self, is_chord_element):
1258 if self.style and is_chord_element:
1259 return "\\tweak #'style #%s" % self.style
1262 def ly_expression (self):
1263 return self.pre_chord_ly ()
1267 def __init__ (self):
1271 return self.ly_expression()
1272 def ly_expression (self):
1273 return pitch_generating_function (self)
1275 class ChordModification:
1276 def __init__ (self):
1280 def ly_expression (self):
1282 val = {1: ".", -1: "^" }.get (self.type, "")
1283 val += "%s" % self.step
1284 val += {1: "+", -1: "-"}.get (self.alteration, "")
1289 class ChordNameEvent (Event):
1290 def __init__ (self):
1291 Event.__init__ (self)
1294 self.duration = None
1295 self.modifications = []
1297 def add_modification (self, mod):
1298 self.modifications.append (mod)
1299 def ly_expression (self):
1302 value = self.root.ly_expression ()
1304 value += self.duration.ly_expression ()
1308 # First print all additions/changes, and only afterwards all subtractions
1309 for m in self.modifications:
1311 value += m.ly_expression ()
1312 for m in self.modifications:
1314 value += m.ly_expression ()
1316 value += "/+%s" % self.bass.ly_expression ()
1320 class TremoloEvent (ArticulationEvent):
1321 def __init__ (self):
1322 Event.__init__ (self)
1325 def ly_expression (self):
1327 if self.bars and self.bars > 0:
1328 str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
1331 class BendEvent (ArticulationEvent):
1332 def __init__ (self):
1333 Event.__init__ (self)
1335 def ly_expression (self):
1336 if self.alter != None:
1337 return "-\\bendAfter #%s" % self.alter
1341 class RhythmicEvent(Event):
1342 def __init__ (self):
1343 Event.__init__ (self)
1344 self.duration = Duration()
1345 self.associated_events = []
1347 def add_associated_event (self, ev):
1349 self.associated_events.append (ev)
1351 def pre_chord_ly (self):
1352 return [ev.pre_chord_ly () for ev in self.associated_events]
1354 def pre_note_ly (self, is_chord_element):
1355 return [ev.pre_note_ly (is_chord_element) for ev in self.associated_events]
1357 def ly_expression_pre_note (self, is_chord_element):
1358 res = string.join (self.pre_note_ly (is_chord_element), ' ')
1363 def get_length (self):
1364 return self.duration.get_length()
1366 def get_properties (self):
1367 return ("'duration %s"
1368 % self.duration.lisp_expression ())
1370 class RestEvent (RhythmicEvent):
1371 def __init__ (self):
1372 RhythmicEvent.__init__ (self)
1375 def ly_expression (self):
1376 res = self.ly_expression_pre_note (False)
1378 return res + "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
1380 return 'r%s' % self.duration.ly_expression ()
1382 def print_ly (self, printer):
1383 for ev in self.associated_events:
1384 ev.print_ly (printer)
1386 self.pitch.print_ly (printer)
1387 self.duration.print_ly (printer)
1391 self.duration.print_ly (printer)
1393 class SkipEvent (RhythmicEvent):
1394 def ly_expression (self):
1395 return 's%s' % self.duration.ly_expression ()
1397 class NoteEvent(RhythmicEvent):
1398 def __init__ (self):
1399 RhythmicEvent.__init__ (self)
1401 self.drum_type = None
1402 self.cautionary = False
1403 self.forced_accidental = False
1405 def get_properties (self):
1406 str = RhythmicEvent.get_properties (self)
1409 str += self.pitch.lisp_expression ()
1410 elif self.drum_type:
1411 str += "'drum-type '%s" % self.drum_type
1415 def pitch_mods (self):
1418 excl_question += '?'
1419 if self.forced_accidental:
1420 excl_question += '!'
1422 return excl_question
1424 def ly_expression (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%s' % (self.pitch.ly_expression (),
1430 self.duration.ly_expression ())
1431 elif self.drum_type:
1432 return res + '%s%s' (self.drum_type,
1433 self.duration.ly_expression ())
1435 def chord_element_ly (self):
1436 # obtain all stuff that needs to be printed before the note:
1437 res = self.ly_expression_pre_note (True)
1439 return res + '%s%s' % (self.pitch.ly_expression (),
1441 elif self.drum_type:
1442 return res + '%s%s' (self.drum_type)
1445 def print_ly (self, printer):
1446 for ev in self.associated_events:
1447 ev.print_ly (printer)
1449 self.pitch.print_ly (printer)
1450 printer (self.pitch_mods ())
1452 printer (self.drum_type)
1454 self.duration.print_ly (printer)
1456 class KeySignatureChange (Music):
1457 def __init__ (self):
1458 Music.__init__ (self)
1461 self.non_standard_alterations = None
1463 def format_non_standard_alteration (self, a):
1464 alter_dict = { -2: ",DOUBLE-FLAT",
1465 -1.5: ",THREE-Q-FLAT",
1471 1.5: ",THREE-Q-SHARP",
1474 accidental = alter_dict[a[1]]
1476 ly.warning (_ ("Unable to convert alteration %s to a lilypond expression") % a[1])
1479 return "( %s . %s )" % (a[0], accidental)
1481 return "(( %s . %s ) . %s )" % (a[2], a[0], accidental)
1485 def ly_expression (self):
1487 return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
1489 elif self.non_standard_alterations:
1490 alterations = [self.format_non_standard_alteration (a) for
1491 a in self.non_standard_alterations]
1492 return "\\set Staff.keySignature = #`(%s)" % string.join (alterations, " ")
1496 class TimeSignatureChange (Music):
1497 def __init__ (self):
1498 Music.__init__ (self)
1499 self.fractions = [4,4]
1501 def format_fraction (self, frac):
1502 if isinstance (frac, list):
1503 l = [self.format_fraction (f) for f in frac]
1504 return "(" + string.join (l, " ") + ")"
1508 def ly_expression (self):
1510 # Print out the style if we have ome, but the '() should only be
1511 # forced for 2/2 or 4/4, since in all other cases we'll get numeric
1512 # signatures anyway despite the default 'C signature style!
1513 is_common_signature = self.fractions in ([2,2], [4,4], [4,2])
1515 if self.style == "common":
1516 st = "\\defaultTimeSignature"
1517 elif (self.style != "'()"):
1518 st = "\\once \\override Staff.TimeSignature #'style = #%s " % self.style
1519 elif (self.style != "'()") or is_common_signature:
1520 st = "\\numericTimeSignature"
1522 # Easy case: self.fractions = [n,d] => normal \time n/d call:
1523 if len (self.fractions) == 2 and isinstance (self.fractions[0], int):
1524 return st + '\\time %d/%d ' % tuple (self.fractions)
1525 elif self.fractions:
1526 return st + "\\compoundMeter #'%s" % self.format_fraction (self.fractions)
1530 class ClefChange (Music):
1531 def __init__ (self):
1532 Music.__init__ (self)
1537 def octave_modifier (self):
1538 return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
1539 def clef_name (self):
1540 return {('G', 2): "treble",
1542 ('C', 1): "soprano",
1543 ('C', 2): "mezzosoprano",
1546 ('C', 5): "baritone",
1547 ('F', 3): "varbaritone",
1549 ('F', 5): "subbass",
1550 ("percussion", 2): "percussion",
1551 # Workaround: MuseScore uses PERC instead of percussion
1552 ("PERC", 2): "percussion",
1553 ("TAB", 5): "tab"}.get ((self.type, self.position), None)
1554 def ly_expression (self):
1555 return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
1558 "G": ("clefs.G", -2, -6),
1559 "C": ("clefs.C", 0, 0),
1560 "F": ("clefs.F", 2, 6),
1563 def lisp_expression (self):
1565 (glyph, pos, c0) = self.clef_dict[self.type]
1569 (make-music 'SequentialMusic
1572 (make-property-set 'clefGlyph "%s") 'Staff)
1574 (make-property-set 'clefPosition %d) 'Staff)
1576 (make-property-set 'middleCPosition %d) 'Staff)))
1577 """ % (glyph, pos, c0)
1580 class Transposition (Music):
1581 def __init__ (self):
1582 Music.__init__ (self)
1584 def ly_expression (self):
1585 self.pitch._force_absolute_pitch = True
1586 return '\\transposition %s' % self.pitch.ly_expression ()
1588 class StaffChange (Music):
1589 def __init__ (self, staff):
1590 Music.__init__ (self)
1592 def ly_expression (self):
1594 return "\\change Staff=\"%s\"" % self.staff
1598 class SetEvent (Music):
1599 def __init__ (self, contextprop, value):
1600 Music.__init__ (self)
1601 self.context_prop = contextprop
1603 def ly_expression (self):
1605 return "\\set %s = %s" % (self.context_prop, self.value)
1609 class StaffLinesEvent (Music):
1610 def __init__ (self, lines):
1611 Music.__init__ (self)
1613 def ly_expression (self):
1614 if (self.lines > 0):
1615 return "\\stopStaff \\override Staff.StaffSymbol #'line-count = #%s \\startStaff" % self.lines
1617 return "\\stopStaff \\revert Staff.StaffSymbol #'line-count \\startStaff"
1619 class TempoMark (Music):
1620 def __init__ (self):
1621 Music.__init__ (self)
1622 self.baseduration = None
1623 self.newduration = None
1625 self.parentheses = False
1626 def set_base_duration (self, dur):
1627 self.baseduration = dur
1628 def set_new_duration (self, dur):
1629 self.newduration = dur
1630 def set_beats_per_minute (self, beats):
1632 def set_parentheses (self, parentheses):
1633 self.parentheses = parentheses
1634 def wait_for_note (self):
1636 def duration_to_markup (self, dur):
1638 # Generate the markup to print the note, use scheme mode for
1639 # ly_expression to get longa and not \longa (which causes an error)
1640 return "\\general-align #Y #DOWN \\smaller \\note #\"%s\" #UP" % dur.ly_expression(None, True)
1643 def tempo_markup_template (self):
1644 return "\\mark\\markup { \\fontsize #-2 \\line { %s } }"
1645 def ly_expression (self):
1647 if not self.baseduration:
1650 if self.parentheses:
1651 res += "\\tempo \"\" %s=%s" % (self.baseduration.ly_expression(), self.beats)
1653 res += "\\tempo %s=%s" % (self.baseduration.ly_expression(), self.beats)
1654 elif self.newduration:
1655 dm = self.duration_to_markup (self.baseduration)
1656 ndm = self.duration_to_markup (self.newduration)
1657 if self.parentheses:
1658 contents = "\"(\" %s = %s \")\"" % (dm, ndm)
1660 contents = " %s = %s " % (dm, ndm)
1661 res += self.tempo_markup_template() % contents
1666 class FiguredBassNote (Music):
1667 def __init__ (self):
1668 Music.__init__ (self)
1672 def set_prefix (self, prefix):
1673 self.prefix = prefix
1674 def set_suffix (self, suffix):
1675 self.prefix = suffix
1676 def set_number (self, number):
1677 self.number = number
1678 def ly_expression (self):
1691 class FiguredBassEvent (NestedMusic):
1692 def __init__ (self):
1693 NestedMusic.__init__ (self)
1694 self.duration = None
1695 self.real_duration = 0
1696 self.parentheses = False
1698 def set_duration (self, dur):
1700 def set_parentheses (self, par):
1701 self.parentheses = par
1702 def set_real_duration (self, dur):
1703 self.real_duration = dur
1705 def print_ly (self, printer):
1706 figured_bass_events = [e for e in self.elements if
1707 isinstance (e, FiguredBassNote)]
1708 if figured_bass_events:
1710 for x in figured_bass_events:
1711 notes.append (x.ly_expression ())
1712 contents = string.join (notes)
1713 if self.parentheses:
1714 contents = '[%s]' % contents
1715 printer ('<%s>' % contents)
1716 self.duration.print_ly (printer)
1719 class MultiMeasureRest(Music):
1721 def lisp_expression (self):
1724 'MultiMeasureRestMusicGroup
1726 (list (make-music (quote BarCheck))
1731 'MultiMeasureRestEvent
1734 (make-music (quote BarCheck))))
1735 """ % self.duration.lisp_expression ()
1737 def ly_expression (self):
1738 return 'R%s' % self.duration.ly_expression ()
1741 class Break (Music):
1742 def __init__ (self, tp="break"):
1743 Music.__init__ (self)
1745 def print_ly (self, printer):
1747 printer.dump ("\\%s" % self.type)
1750 def __init__ (self, command = "StaffGroup"):
1751 self.stafftype = command
1753 self.instrument_name = None
1754 self.short_instrument_name = None
1758 self.is_group = True
1759 self.context_modifications = []
1760 # part_information is a list with entries of the form
1761 # [staffid, voicelist]
1762 # where voicelist is a list with entries of the form
1763 # [voiceid1, [lyricsid11, lyricsid12,...] ]
1764 self.part_information = None
1766 def append_staff (self, staff):
1767 self.children.append (staff)
1769 def set_part_information (self, part_name, staves_info):
1770 if part_name == self.id:
1771 self.part_information = staves_info
1773 for c in self.children:
1774 c.set_part_information (part_name, staves_info)
1776 def add_context_modification (self, modification):
1777 self.context_modifications.append (modification)
1779 def print_ly_contents (self, printer):
1780 for c in self.children:
1782 c.print_ly (printer)
1783 def needs_with (self):
1785 needs_with |= self.spanbar == "no"
1786 needs_with |= self.instrument_name != None
1787 needs_with |= self.short_instrument_name != None
1788 needs_with |= (self.symbol != None) and (self.symbol != "bracket")
1790 def print_ly_context_mods (self, printer):
1791 if self.instrument_name or self.short_instrument_name:
1792 printer.dump ("\\consists \"Instrument_name_engraver\"")
1793 if self.spanbar == "no":
1794 printer.dump ("\\override SpanBar #'transparent = ##t")
1795 brack = {"brace": "SystemStartBrace",
1796 "none": "SystemStartBar",
1797 "line": "SystemStartSquare"}.get (self.symbol, None)
1799 printer.dump ("systemStartDelimiter = #'%s" % brack)
1801 def print_ly_overrides (self, printer):
1802 needs_with = self.needs_with () | (len (self.context_modifications) > 0);
1804 printer.dump ("\\with {")
1805 self.print_ly_context_mods (printer)
1806 for m in self.context_modifications:
1810 def print_ly (self, printer):
1812 printer.dump ("\\new %s" % self.stafftype)
1813 self.print_ly_overrides (printer)
1816 if self.stafftype and self.instrument_name:
1817 printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
1818 escape_instrument_string (self.instrument_name)))
1820 if self.stafftype and self.short_instrument_name:
1821 printer.dump ("\\set %s.shortInstrumentName = %s" % (self.stafftype,
1822 escape_instrument_string (self.short_instrument_name)))
1824 self.print_ly_contents (printer)
1830 class Staff (StaffGroup):
1831 def __init__ (self, command = "Staff"):
1832 StaffGroup.__init__ (self, command)
1833 self.is_group = False
1835 self.voice_command = "Voice"
1836 self.substafftype = None
1838 def needs_with (self):
1840 def print_ly_context_mods (self, printer):
1843 def print_ly_contents (self, printer):
1844 if not self.id or not self.part_information:
1846 sub_staff_type = self.substafftype
1847 if not sub_staff_type:
1848 sub_staff_type = self.stafftype
1850 for [staff_id, voices] in self.part_information:
1851 # Chord names need to come before the staff itself!
1852 for [v, lyrics, figuredbass, chordnames] in voices:
1854 printer ('\context ChordNames = "%s" \\%s' % (chordnames, chordnames))
1856 # now comes the real staff definition:
1858 printer ('\\context %s = "%s" << ' % (sub_staff_type, staff_id))
1860 printer ('\\context %s << ' % sub_staff_type)
1863 nr_voices = len (voices)
1864 for [v, lyrics, figuredbass, chordnames] in voices:
1866 voice_count_text = ''
1868 voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo',
1869 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
1870 printer ('\\context %s = "%s" {%s \\%s }' % (self.voice_command, v, voice_count_text, v))
1874 printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
1877 printer ('\context FiguredBass = "%s" \\%s' % (figuredbass, figuredbass))
1880 def print_ly (self, printer):
1881 if self.part_information and len (self.part_information) > 1:
1882 self.stafftype = "PianoStaff"
1883 self.substafftype = "Staff"
1884 StaffGroup.print_ly (self, printer)
1886 class TabStaff (Staff):
1887 def __init__ (self, command = "TabStaff"):
1888 Staff.__init__ (self, command)
1889 self.string_tunings = []
1890 self.tablature_format = None
1891 self.voice_command = "TabVoice"
1892 def print_ly_overrides (self, printer):
1893 if self.string_tunings or self.tablature_format:
1894 printer.dump ("\\with {")
1895 if self.string_tunings:
1896 printer.dump ("stringTunings = #`(")
1897 for i in self.string_tunings:
1898 printer.dump (",%s" % i.lisp_expression ())
1900 if self.tablature_format:
1901 printer.dump ("tablatureFormat = #%s" % self.tablature_format)
1905 class DrumStaff (Staff):
1906 def __init__ (self, command = "DrumStaff"):
1907 Staff.__init__ (self, command)
1908 self.drum_style_table = None
1909 self.voice_command = "DrumVoice"
1910 def print_ly_overrides (self, printer):
1911 if self.drum_style_table:
1912 printer.dump ("\with {")
1913 printer.dump ("drumStyleTable = #%s" % self.drum_style_table)
1916 class RhythmicStaff (Staff):
1917 def __init__ (self, command = "RhythmicStaff"):
1918 Staff.__init__ (self, command)
1921 def __init__ (self):
1922 self.contents = None
1923 self.create_midi = False
1925 def set_contents (self, contents):
1926 self.contents = contents
1928 def set_part_information (self, part_id, staves_info):
1930 self.contents.set_part_information (part_id, staves_info)
1932 def print_ly (self, printer):
1933 self.create_midi = get_create_midi ()
1934 printer.dump ("\\score {");
1937 self.contents.print_ly (printer);
1938 printer.dump ("\\layout {}");
1940 if not self.create_midi:
1941 printer.dump ("% To create MIDI output, uncomment the following line:");
1943 printer.dump ("% ");
1944 printer.dump ("\\midi {}");
1952 bflat.alteration = -1
1962 print bflat.semitones()
1963 print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
1964 print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
1966 print bflat.semitones(), 'down'
1967 print bflat.transposed (down)
1968 print bflat.transposed (down).transposed (down)
1969 print bflat.transposed (down).transposed (down).transposed (down)
1973 def test_printer ():
1981 m = SequentialMusic()
1982 m.append (make_note ())
1983 m.append (make_note ())
1984 m.append (make_note ())
1987 t = TimeScaledMusic ()
1993 m = SequentialMusic ()
1994 m.append (make_tup ())
1995 m.append (make_tup ())
1996 m.append (make_tup ())
1998 printer = Output_printer()
1999 m.print_ly (printer)
2003 m = SequentialMusic()
2007 n.duration.duration_log = l
2009 evc.insert_around (None, n, 0)
2010 m.insert_around (None, evc, 0)
2014 n.duration.duration_log = l
2016 evc.insert_around (None, n, 0)
2017 m.insert_around (None, evc, 0)
2021 n.duration.duration_log = l
2023 evc.insert_around (None, n, 0)
2024 m.insert_around (None, evc, 0)
2028 m.insert_around (None, evc, 0)
2033 tonic.alteration = -2
2034 n = KeySignatureChange()
2035 n.tonic=tonic.copy()
2036 n.scale = [0, 0, -2, 0, 0,-2,-2]
2038 evc.insert_around (None, n, 0)
2039 m.insert_around (None, evc, 0)
2044 if __name__ == '__main__':
2050 expr.set_start (Rational (0))
2051 print expr.ly_expression()
2052 start = Rational (0,4)
2053 stop = Rational (4,2)
2054 def sub(x, start=start, stop=stop):
2055 ok = x.start >= start and x.start +x.get_length() <= stop
2058 print expr.lisp_sub_expression(sub)