+ elts = []
+ attr_dispatch = {
+ 'clef': musicxml_clef_to_lily,
+ 'time': musicxml_time_to_lily,
+ 'key': musicxml_key_to_lily
+ }
+ for (k, func) in attr_dispatch.items ():
+ childs = attrs.get_named_children (k)
+
+ ## ugh: you get clefs spread over staves for piano
+ if childs:
+ elts.append (func (attrs))
+
+ return elts
+
+spanner_event_dict = {
+ 'slur' : musicexp.SlurEvent,
+ 'beam' : musicexp.BeamEvent,
+}
+spanner_type_dict = {
+ 'start': -1,
+ 'begin': -1,
+ 'stop': 1,
+ 'end' : 1
+}
+
+def musicxml_spanner_to_lily_event (mxl_event):
+ ev = None
+
+ name = mxl_event.get_name()
+ try:
+ func = spanner_event_dict[name]
+ ev = func()
+ except KeyError:
+ print 'unknown span event ', mxl_event
+
+ try:
+ key = mxl_event.get_type ()
+ ev.span_direction = spanner_type_dict[key]
+ except KeyError:
+ print 'unknown span type', key, 'for', name
+
+ return ev
+
+instrument_drumtype_dict = {
+ 'Acoustic Snare Drum': 'acousticsnare',
+ 'Side Stick': 'sidestick',
+ 'Open Triangle': 'opentriangle',
+ 'Mute Triangle': 'mutetriangle',
+ 'Tambourine': 'tambourine',
+
+}
+
+def musicxml_note_to_lily_main_event (n):
+ pitch = None
+ duration = None
+
+ mxl_pitch = n.get_maybe_exist_typed_child (musicxml.Pitch)
+ event = None
+ if mxl_pitch:
+ pitch = musicxml_pitch_to_lily (mxl_pitch)
+ event = musicexp.NoteEvent()
+ event.pitch = pitch
+
+ acc = n.get_maybe_exist_named_child ('accidental')
+ if acc:
+ # let's not force accs everywhere.
+ event.cautionary = acc.editorial
+
+ elif n.get_maybe_exist_typed_child (musicxml.Rest):
+ event = musicexp.RestEvent()
+ elif n.instrument_name:
+ event = musicexp.NoteEvent ()
+ try:
+ event.drum_type = instrument_drumtype_dict[n.instrument_name]
+ except KeyError:
+ n.message ("drum %s type unknow, please add to instrument_drumtype_dict" % n.instrument_name)
+ event.drum_type = 'acousticsnare'
+
+ if not event:
+ n.message ("cannot find suitable event")
+
+ event.duration = musicxml_duration_to_lily (n)
+ return event
+
+
+## todo
+class NegativeSkip:
+ def __init__ (self, here, dest):
+ self.here = here
+ self.dest = dest
+
+class LilyPondVoiceBuilder:
+ def __init__ (self):
+ self.elements = []
+ self.end_moment = Rational (0)
+ self.begin_moment = Rational (0)
+ self.pending_multibar = Rational (0)
+
+ def _insert_multibar (self):
+ r = musicexp.MultiMeasureRest ()
+ r.duration = musicexp.Duration()
+ r.duration.duration_log = 0
+ r.duration.factor = self.pending_multibar
+ self.elements.append (r)
+ self.begin_moment = self.end_moment
+ self.end_moment = self.begin_moment + self.pending_multibar
+ self.pending_multibar = Rational (0)
+
+ def add_multibar_rest (self, duration):
+ self.pending_multibar += duration
+
+
+ def add_music (self, music, duration):
+ assert isinstance (music, musicexp.Music)
+ if self.pending_multibar > Rational (0):
+ self._insert_multibar ()
+
+ self.elements.append (music)
+ self.begin_moment = self.end_moment
+ self.end_moment = self.begin_moment + duration
+
+ def add_bar_check (self, number):
+ b = musicexp.BarCheck ()
+ b.bar_number = number
+ self.add_music (b, Rational (0))
+
+ def jumpto (self, moment):
+ current_end = self.end_moment + self.pending_multibar
+ diff = moment - current_end
+
+ if diff < Rational (0):
+ print 'Negative skip', diff
+ diff = Rational (0)
+
+ if diff > Rational (0):
+ skip = musicexp.SkipEvent()
+ skip.duration.duration_log = 0
+ skip.duration.factor = diff
+
+ evc = musicexp.EventChord ()
+ evc.elements.append (skip)
+ self.add_music (evc, diff)
+
+ def last_event_chord (self, starting_at):
+
+ value = None
+ if (self.elements
+ and isinstance (self.elements[-1], musicexp.EventChord)
+ and self.begin_moment == starting_at):
+ value = self.elements[-1]
+ else:
+ self.jumpto (starting_at)
+ value = None
+
+ return value
+
+ def correct_negative_skip (self, goto):
+ self.end_moment = goto
+ self.begin_moment = goto
+ evc = musicexp.EventChord ()
+ self.elements.append (evc)
+