class TimeScaledMusic (MusicWrapper):
def __init__ (self):
MusicWrapper.__init__ (self)
+ self.numerator = 1
+ self.denominator = 1
self.display_number = "actual" # valid values "actual" | "both" | None
# Display the basic note length for the tuplet:
self.display_type = None # value values "actual" | "both" | None
self.display_bracket = "bracket" # valid values "bracket" | "curved" | None
+ self.actual_type = None # The actually played unit of the scaling
+ self.normal_type = None # The basic unit of the scaling
+ self.display_numerator = None
+ self.display_denominator = None
def print_ly (self, func):
if self.display_bracket == None:
base_number_function = {None: "#f",
"actual": "tuplet-number::calc-denominator-text",
"both": "tuplet-number::calc-fraction-text"}.get (self.display_number, None)
+ # If we have non-standard numerator/denominator, use our custom function
+ if self.display_number == "actual" and self.display_denominator:
+ base_number_function = "(tuplet-number::non-default-tuplet-denominator-text %s)" % self.display_denominator
+ elif self.display_number == "both" and (self.display_denominator or self.display_numerator):
+ if self.display_numerator:
+ num = self.display_numerator
+ else:
+ num = "#f"
+ if self.display_denominator:
+ den = self.display_denominator
+ else:
+ den = "#f"
+ base_number_function = "(tuplet-number::non-default-tuplet-fraction-text %s %s)" % (den, num)
+
- if self.display_type == "actual":
- base_duration = "8" # TODO!!!
+ if self.display_type == "actual" and self.normal_type:
+ # Obtain the note duration in scheme-mode, i.e. \longa as \\longa
+ base_duration = self.normal_type.ly_expression (None, True)
func ("\\once \\override TupletNumber #'text = #(tuplet-number::append-note-wrapper %s \"%s\")" %
(base_number_function, base_duration))
func.newline ()
- elif self.display_type == None:
+ elif self.display_type == "both": # TODO: Implement this using actual_type and normal_type!
+ warning (_ ("Tuplet brackets displaying both note durations are not implemented, using default"))
if self.display_number == None:
func ("\\once \\override TupletNumber #'stencil = ##f")
func.newline ()
elif self.display_number == "both":
func ("\\once \\override TupletNumber #'text = #%s" % base_number_function)
func.newline ()
- elif self.display_type == "both":
- warning (_ ("Tuplet brackets displaying both note durations are not implemented, using default"))
+ else:
if self.display_number == None:
func ("\\once \\override TupletNumber #'stencil = ##f")
func.newline ()
pitches = []
basepitch = None
for x in note_events:
- pitches.append (x.pitch.ly_expression ())
+ pitches.append (x.chord_element_ly ())
if not basepitch:
basepitch = previous_pitch
printer ('<%s>' % string.join (pitches))
else:
return ''
+
+class FunctionWrapperEvent (Event):
+ def __init__ (self, function_name = None):
+ Event.__init__ (self)
+ self.function_name = function_name
+ def pre_note_ly (self, is_chord_element):
+ if self.function_name:
+ return "\\%s" % self.function_name
+ else:
+ return ''
+ def pre_chord_ly (self):
+ return ''
+ def ly_expression (self):
+ if self.function_name:
+ return "\\%s" % self.function_name
+ else:
+ return ''
+
+class ParenthesizeEvent (FunctionWrapperEvent):
+ def __init__ (self):
+ FunctionWrapperEvent.__init__ (self, "parenthesize")
+
+class NotestyleEvent (Event):
+ def __init__ (self):
+ Event.__init__ (self)
+ self.style = None
+ self.filled = None
+ def pre_chord_ly (self):
+ if self.style:
+ return "\\once \\override NoteHead #'style = #%s" % self.style
+ else:
+ return ''
+ def pre_note_ly (self, is_chord_element):
+ if self.style and is_chord_element:
+ return "\\tweak #'style #%s" % self.style
+ else:
+ return ''
+ def ly_expression (self):
+ return self.pre_chord_ly ()
+
+
class ChordPitch:
def __init__ (self):
self.alteration = 0
def __init__ (self):
Event.__init__ (self)
self.duration = Duration()
-
+ self.associated_events = []
+
+ def add_associated_event (self, ev):
+ if ev:
+ self.associated_events.append (ev)
+
+ def pre_chord_ly (self):
+ return [ev.pre_chord_ly () for ev in self.associated_events]
+
+ def pre_note_ly (self, is_chord_element):
+ return [ev.pre_note_ly (is_chord_element) for ev in self.associated_events]
+
+ def ly_expression_pre_note (self, is_chord_element):
+ res = string.join (self.pre_note_ly (is_chord_element), ' ')
+ if res != '':
+ res = res + ' '
+ return res
+
def get_length (self):
return self.duration.get_length()
def __init__ (self):
RhythmicEvent.__init__ (self)
self.pitch = None
+
def ly_expression (self):
+ res = self.ly_expression_pre_note (False)
if self.pitch:
- return "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
+ return res + "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
else:
return 'r%s' % self.duration.ly_expression ()
def print_ly (self, printer):
+ for ev in self.associated_events:
+ ev.print_ly (printer)
if self.pitch:
self.pitch.print_ly (printer)
self.duration.print_ly (printer)
self.drum_type = None
self.cautionary = False
self.forced_accidental = False
-
+
def get_properties (self):
str = RhythmicEvent.get_properties (self)
excl_question += '!'
return excl_question
-
+
def ly_expression (self):
+ # obtain all stuff that needs to be printed before the note:
+ res = self.ly_expression_pre_note (True)
if self.pitch:
- return '%s%s%s' % (self.pitch.ly_expression (),
+ return res + '%s%s%s' % (self.pitch.ly_expression (),
self.pitch_mods(),
self.duration.ly_expression ())
elif self.drum_type:
- return '%s%s' (self.drum_type,
+ return res + '%s%s' (self.drum_type,
self.duration.ly_expression ())
+ def chord_element_ly (self):
+ # obtain all stuff that needs to be printed before the note:
+ res = self.ly_expression_pre_note (True)
+ if self.pitch:
+ return res + '%s%s' % (self.pitch.ly_expression (),
+ self.pitch_mods())
+ elif self.drum_type:
+ return res + '%s%s' (self.drum_type)
+
+
def print_ly (self, printer):
+ for ev in self.associated_events:
+ ev.print_ly (printer)
if self.pitch:
self.pitch.print_ly (printer)
printer (self.pitch_mods ())