--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.1 Partwise//EN"
+ "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="1.1">
+ <movement-title>Tempo markings</movement-title>
+ <identification/>
+ <defaults/>
+ <part-list>
+ <score-part id="P1">
+ <part-name></part-name>
+ <score-instrument id="P1-I1">
+ <instrument-name>Grand Piano</instrument-name>
+ </score-instrument>
+ <midi-instrument id="P1-I1">
+ <midi-channel>1</midi-channel>
+ <midi-program>1</midi-program>
+ </midi-instrument>
+ </score-part>
+ </part-list>
+ <!--=========================================================-->
+ <part id="P1">
+ <measure number="1" width="527">
+ <attributes>
+ <divisions>1</divisions>
+ <key>
+ <fifths>0</fifths>
+ <mode>major</mode>
+ </key>
+ <time symbol="common">
+ <beats>4</beats>
+ <beat-type>4</beat-type>
+ </time>
+ <clef>
+ <sign>G</sign>
+ <line>2</line>
+ </clef>
+ </attributes>
+ <direction>
+ <direction-type>
+ <metronome>
+ <beat-unit>quarter</beat-unit>
+ <beat-unit-dot/>
+ <per-minute>100</per-minute>
+ </metronome>
+ </direction-type>
+ </direction>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <direction>
+ <direction-type>
+ <words>Adagio</words>
+ </direction-type>\r
+ <direction-type>\r
+ <metronome>\r
+ <beat-unit>long</beat-unit>\r
+ <per-minute>100</per-minute>\r
+ </metronome>\r
+ </direction-type>\r
+ </direction>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ </measure>
+ <!--=======================================================-->
+ <measure number="2">
+ <direction>
+ <direction-type>
+ <metronome>
+ <beat-unit>quarter</beat-unit>
+ <beat-unit-dot/>
+ <beat-unit>half</beat-unit>
+ <beat-unit-dot/>
+ </metronome>
+ </direction-type>
+ </direction>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <direction>\r
+ <direction-type>\r
+ <metronome>\r
+ <beat-unit>long</beat-unit>\r
+ <beat-unit>32nd</beat-unit>\r
+ <beat-unit-dot/>\r
+ </metronome>\r
+ </direction-type>
+ </direction>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ </measure>
+ <!--=======================================================-->
+ <measure number="3">
+ <direction>
+ <direction-type>
+ <metronome parentheses="yes">
+ <beat-unit>quarter</beat-unit>
+ <beat-unit-dot/>
+ <beat-unit>half</beat-unit>
+ <beat-unit-dot/>
+ </metronome>
+ </direction-type>
+ </direction>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <direction>
+ <direction-type>
+ <metronome parentheses="yes">
+ <beat-unit>quarter</beat-unit>
+ <beat-unit-dot/>
+ <per-minute>77</per-minute>
+ </metronome>
+ </direction-type>
+ </direction>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <note>
+ <pitch><step>C</step><octave>5</octave></pitch>
+ <duration>1</duration>
+ <voice>1</voice>
+ <type>quarter</type>
+ </note>
+ <barline location="right">
+ <bar-style>light-heavy</bar-style>
+ </barline>
+ </measure>
+ </part>
+ <!--=========================================================-->
+</score-partwise>
self.factor.denominator ())
- def ly_expression (self, factor = None):
+ def ly_expression (self, factor = None, scheme_mode = False):
if not factor:
factor = self.factor
if self.duration_log < 0:
- str = {-1: "\\breve", -2: "\\longa"}.get (self.duration_log, "1")
+ if scheme_mode:
+ longer_dict = {-1: "breve", -2: "longa"}
+ else:
+ longer_dict = {-1: "\\breve", -2: "\\longa"}
+ str = longer_dict.get (self.duration_log, "1")
else:
str = '%d' % (1 << self.duration_log)
str += '.'*self.dots
else:
return ''
+
+class TempoMark (Music):
+ def __init__ (self):
+ Music.__init__ (self)
+ self.baseduration = None
+ self.newduration = None
+ self.beats = None
+ self.parentheses = False
+ def set_base_duration (self, dur):
+ self.baseduration = dur
+ def set_new_duration (self, dur):
+ self.newduration = dur
+ def set_beats_per_minute (self, beats):
+ self.beats = beats
+ def set_parentheses (self, parentheses):
+ self.parentheses = parentheses
+ def wait_for_note (self):
+ return False
+ def duration_to_markup (self, dur):
+ if dur:
+ # Generate the markup to print the note, use scheme mode for
+ # ly_expression to get longa and not \longa (which causes an error)
+ return "\\general-align #Y #DOWN \\smaller \\note #\"%s\" #UP" % dur.ly_expression(None, True)
+ else:
+ return ''
+ def tempo_markup_template (self):
+ return "\\mark\\markup { \\fontsize #-2 \\line { %s } }"
+ def ly_expression (self):
+ res = ''
+ if not self.baseduration:
+ return res
+ if self.beats:
+ if self.parentheses:
+ dm = self.duration_to_markup (self.baseduration)
+ contents = "\"(\" %s = %s \")\"" % (dm, self.beats)
+ res += self.tempo_markup_template() % contents
+ else:
+ res += "\\tempo %s=%s" % (self.baseduration.ly_expression(), self.beats)
+ elif self.newduration:
+ dm = self.duration_to_markup (self.baseduration)
+ ndm = self.duration_to_markup (self.newduration)
+ if self.parentheses:
+ contents = "\"(\" %s = %s \")\"" % (dm, ndm)
+ else:
+ contents = " %s = %s " % (dm, ndm)
+ res += self.tempo_markup_template() % contents
+ else:
+ return ''
+ return res
+
class FiguredBassNote (Music):
def __init__ (self):
Music.__init__ (self)
return return_string
+def musicxml_duration_to_log (dur):
+ return {'256th': 8,
+ '128th': 7,
+ '64th': 6,
+ '32nd': 5,
+ '16th': 4,
+ 'eighth': 3,
+ 'quarter': 2,
+ 'half': 1,
+ 'whole': 0,
+ 'breve': -1,
+ 'longa': -2,
+ 'long': -2}.get (dur, 0)
+
+
+
class Xml_node:
def __init__ (self):
self._children = []
if ch:
log = ch.get_text ().strip()
- return {'256th': 8,
- '128th': 7,
- '64th': 6,
- '32nd': 5,
- '16th': 4,
- 'eighth': 3,
- 'quarter': 2,
- 'half': 1,
- 'whole': 0,
- 'breve': -1,
- 'longa': -2}.get (log, 0)
+ return musicxml_duration_to_log (log)
elif self.get_maybe_exist_named_child (u'grace'):
# FIXME: is it ok to default to eight note for grace notes?
return 3
class FiguredBass (Music_xml_node):
pass
+class BeatUnit (Music_xml_node):
+ pass
+
+class BeatUnitDot (Music_xml_node):
+ pass
+
+class PerMinute (Music_xml_node):
+ pass
+
## need this, not all classes are instantiated
'barline': Barline,
'bar-style': BarStyle,
'beam' : Beam,
+ 'beat-unit': BeatUnit,
+ 'beat-unit-dot': BeatUnitDot,
'bend' : Bend,
'bracket' : Bracket,
'chord': Chord,
'part-group': Part_group,
'part-list': Part_list,
'pedal': Pedal,
+ 'per-minute': PerMinute,
'pitch': Pitch,
'rest': Rest,
'score-part': Score_part,
needed_additional_definitions.append ("eyeglasses")
return musicexp.MarkEvent ("\\eyeglasses")
+def next_non_hash_index (lst, pos):
+ pos += 1
+ while pos < len (lst) and isinstance (lst[pos], musicxml.Hash_text):
+ pos += 1
+ return pos
+
+def musicxml_metronome_to_ly (mxl_event):
+ children = mxl_event.get_all_children ()
+ if not children:
+ return
+
+ index = -1
+ index = next_non_hash_index (children, index)
+ if isinstance (children[index], musicxml.BeatUnit):
+ # first form of metronome-mark, using unit and beats/min or other unit
+ ev = musicexp.TempoMark ()
+ if hasattr (mxl_event, 'parentheses'):
+ ev.set_parentheses (mxl_event.parentheses == "yes")
+
+ d = musicexp.Duration ()
+ d.duration_log = musicxml.musicxml_duration_to_log (children[index].get_text ())
+ index = next_non_hash_index (children, index)
+ if isinstance (children[index], musicxml.BeatUnitDot):
+ d.dots = 1
+ index = next_non_hash_index (children, index)
+ ev.set_base_duration (d)
+ if isinstance (children[index], musicxml.BeatUnit):
+ # Form "note = newnote"
+ newd = musicexp.Duration ()
+ newd.duration_log = musicxml.musicxml_duration_to_log (children[index].get_text ())
+ index = next_non_hash_index (children, index)
+ if isinstance (children[index], musicxml.BeatUnitDot):
+ newd.dots = 1
+ index = next_non_hash_index (children, index)
+ ev.set_new_duration (newd)
+ elif isinstance (children[index], musicxml.PerMinute):
+ # Form "note = bpm"
+ try:
+ beats = int (children[index].get_text ())
+ ev.set_beats_per_minute (beats)
+ except ValueError:
+ pass
+ else:
+ error_message (_ ("Unknown metronome mark, ignoring"))
+ return
+ return ev
+ else:
+ #TODO: Implement the other (more complex) way for tempo marks!
+ error_message (_ ("Metronome marks with complex relations (<metronome-note> in MusicXML) are not yet implemented."))
+ return
+
# translate directions into Events, possible values:
# -) string (MarkEvent with that command)
# -) function (function(mxl_event) needs to return a full Event-derived object
# 'damp' : ???
# 'damp-all' : ???
'eyeglasses': musicxml_eyeglasses_to_ly,
-# 'harp-pedals' :
-# 'image' :
-# 'metronome' :
+# 'harp-pedals' : ???
+# 'image' : ???
+ 'metronome' : musicxml_metronome_to_ly,
'rehearsal' : musicxml_rehearsal_to_ly_mark,
-# 'scordatura' :
+# 'scordatura' : ???
'segno' : (musicexp.MusicGlyphMarkEvent, "segno"),
'words' : musicxml_words_to_lily_event,
}
res.append (note)
dur = n.get_maybe_exist_named_child ('duration')
if dur:
- # TODO: implement duration (given in base steps!)
# apply the duration to res
length = Rational(int(dur.get_text()), n._divisions)*Rational(1,4)
res.set_real_duration (length)