]> git.donarmstrong.com Git - lilypond.git/commitdiff
MusicXML: Implement Barline styles and repeats in musicxml2ly
authorReinhold Kainhofer <reinhold@kainhofer.com>
Fri, 19 Oct 2007 00:52:38 +0000 (02:52 +0200)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Fri, 19 Oct 2007 00:52:38 +0000 (02:52 +0200)
-) The <barline> element is now converted to a \bar"...." lilypond
   expression. Not all bar styles from MusicXML are supported by lilypond,
   though.

-) Convert repeats and alternative endings from MusicXML to lilypond.
   While lilypond has a nice hierarchy (i.e. nested music) for repeating
   structures, MusicXML only has markers "here starts/ends a repeat or
   altern.ending", so I need to somehow build up that repeat hierarchy
   from the flat data. I've imlemented this via a loop that looks for
   a repeat structure, replaces that one repeat by a proper instance
   of musicexp.RepeatedMusic. Since I directly modify the list of
   event chords, after replacing one repeat, I have to start the
   whole loop from the start (because the iterators are off after
   the list is modified).

-) Add some more unit test files for barlines and repeating structures
   (some even do not make sense from a musical point of view)

-) Fix typo in the coverage/regression tests make file

13 files changed:
input/regression/musicxml/09a-Repeats-Finale.xml [deleted file]
input/regression/musicxml/09a-SimpleRepeat-Finale.xml [new file with mode: 0644]
input/regression/musicxml/09b-Barlines-Finale.xml [deleted file]
input/regression/musicxml/09b-RepeatWithAlternatives-Finale.xml [new file with mode: 0644]
input/regression/musicxml/09c-Barlines-Finale.xml [new file with mode: 0644]
input/regression/musicxml/09d-RepeatMultipleTimes-Finale.xml [new file with mode: 0644]
input/regression/musicxml/09e-Alternatives-Finale.xml [new file with mode: 0644]
input/regression/musicxml/09f-Repeats-Finale.xml [new file with mode: 0644]
input/regression/musicxml/09g-Endings-Finale.xml [new file with mode: 0644]
input/regression/musicxml/GNUmakefile
python/musicexp.py
python/musicxml.py
scripts/musicxml2ly.py

diff --git a/input/regression/musicxml/09a-Repeats-Finale.xml b/input/regression/musicxml/09a-Repeats-Finale.xml
deleted file mode 100644 (file)
index ec5bb43..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
-                                "http://www.musicxml.org/dtds/partwise.dtd">\r
-<score-partwise>\r
-  <movement-title>Finale Repeat test</movement-title>\r
-  <identification>\r
-    <creator type="composer">Reinhold Kainhofer</creator>\r
-    <rights>Public Domain</rights>\r
-    <encoding>\r
-      <software>Finale 2007 for Windows</software>\r
-      <software>Dolet Light for Finale 2007</software>\r
-      <encoding-date>2007-08-31</encoding-date>\r
-    </encoding>\r
-  </identification>\r
-  <part-list>\r
-    <score-part id="P1">\r
-      <part-name>MusicXML Part</part-name>\r
-      <score-instrument id="P1-I1">\r
-        <instrument-name>Grand Piano</instrument-name>\r
-      </score-instrument>\r
-      <midi-instrument id="P1-I1">\r
-        <midi-channel>1</midi-channel>\r
-        <midi-program>1</midi-program>\r
-      </midi-instrument>\r
-    </score-part>\r
-  </part-list>\r
-  <!--=========================================================-->\r
-  <part id="P1">\r
-    <measure number="1">\r
-      <attributes>\r
-        <divisions>1</divisions>\r
-        <key>\r
-          <fifths>0</fifths>\r
-          <mode>major</mode>\r
-        </key>\r
-        <time symbol="common">\r
-          <beats>4</beats>\r
-          <beat-type>4</beat-type>\r
-        </time>\r
-        <clef>\r
-          <sign>G</sign>\r
-          <line>2</line>\r
-        </clef>\r
-      </attributes>\r
-      <sound tempo="120"/>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="2">\r
-      <barline location="left">\r
-        <ending number="1" type="start"/>\r
-      </barline>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-      <barline location="right">\r
-        <bar-style>light-heavy</bar-style>\r
-        <ending number="1" type="stop"/>\r
-        <repeat direction="backward"/>\r
-      </barline>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="3">\r
-      <barline location="left">\r
-        <ending number="2" type="start"/>\r
-      </barline>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-      <barline location="right">\r
-        <ending number="2" type="discontinue"/>\r
-      </barline>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="4">\r
-      <print new-system="yes"/>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="5">\r
-      <barline location="left">\r
-        <bar-style>heavy-light</bar-style>\r
-        <repeat direction="forward"/>\r
-      </barline>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-      <barline location="right">\r
-        <bar-style>light-heavy</bar-style>\r
-        <repeat direction="backward"/>\r
-      </barline>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="6">\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="7">\r
-      <print new-system="yes"/>\r
-      <barline location="left">\r
-        <ending number="1" type="start"/>\r
-      </barline>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-      <barline location="right">\r
-        <bar-style>light-heavy</bar-style>\r
-        <ending number="1" type="stop"/>\r
-        <repeat direction="backward"/>\r
-      </barline>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="8">\r
-      <barline location="left">\r
-        <bar-style>heavy-light</bar-style>\r
-        <repeat direction="forward"/>\r
-      </barline>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="9">\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-      <barline location="right">\r
-        <bar-style>light-heavy</bar-style>\r
-        <repeat direction="backward"/>\r
-      </barline>\r
-    </measure>\r
-    <!--=======================================================-->\r
-    <measure number="10">\r
-      <print new-system="yes"/>\r
-      <note>\r
-        <rest/>\r
-        <duration>4</duration>\r
-        <voice>1</voice>\r
-      </note>\r
-      <barline location="right">\r
-        <bar-style>light-heavy</bar-style>\r
-      </barline>\r
-    </measure>\r
-  </part>\r
-  <!--=========================================================-->\r
-</score-partwise>\r
diff --git a/input/regression/musicxml/09a-SimpleRepeat-Finale.xml b/input/regression/musicxml/09a-SimpleRepeat-Finale.xml
new file mode 100644 (file)
index 0000000..cf34f14
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+  <identification>\r
+    <encoding>\r
+      <software>Finale 2007 for Windows</software>\r
+      <software>Dolet Light for Finale 2007</software>\r
+      <encoding-date>2007-10-17</encoding-date>\r
+    </encoding>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+      <score-instrument id="P1-I1">\r
+        <instrument-name>Grand Piano</instrument-name>\r
+      </score-instrument>\r
+      <midi-instrument id="P1-I1">\r
+        <midi-channel>1</midi-channel>\r
+        <midi-program>1</midi-program>\r
+      </midi-instrument>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <sound tempo="120"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <repeat direction="backward" times="5"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="2">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
diff --git a/input/regression/musicxml/09b-Barlines-Finale.xml b/input/regression/musicxml/09b-Barlines-Finale.xml
deleted file mode 100644 (file)
index e3d1a92..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"
-                                "http://www.musicxml.org/dtds/partwise.dtd">
-<score-partwise>
-  <movement-title>Barline test</movement-title>
-  <identification>
-    <creator type="composer">Reinhold Kainhofer</creator>
-    <rights>Public Domain</rights>
-    <encoding>
-      <software>Finale 2007 for Windows</software>
-      <software>Dolet Light for Finale 2007</software>
-      <encoding-date>2007-09-21</encoding-date>
-    </encoding>
-  </identification>
-  <part-list>
-    <score-part id="P1">
-      <part-name>MusicXML Part</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">
-      <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>
-      <sound tempo="120"/>
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-      <barline location="right">
-        <bar-style>light-light</bar-style>
-      </barline>
-    </measure>
-    <!--=======================================================-->
-    <measure number="2">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-      <barline location="right">
-        <bar-style>light-heavy</bar-style>
-      </barline>
-    </measure>
-    <!--=======================================================-->
-    <measure number="3">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-      <barline location="right">
-        <bar-style>heavy</bar-style>
-      </barline>
-    </measure>
-    <!--=======================================================-->
-    <measure number="4">
-      <print new-system="yes"/>
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-      <barline location="right">
-        <bar-style>dashed</bar-style>
-      </barline>
-    </measure>
-    <!--=======================================================-->
-    <measure number="5">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-      <barline location="right">
-        <bar-style>dotted</bar-style>
-      </barline>
-    </measure>
-    <!--=======================================================-->
-    <measure number="6">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-      <barline location="right">
-        <bar-style>none</bar-style>
-      </barline>
-    </measure>
-    <!--=======================================================-->
-    <measure number="7">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-    </measure>
-    <!--=======================================================-->
-    <measure number="8">
-      <print new-system="yes"/>
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-    </measure>
-    <!--=======================================================-->
-    <measure number="9">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-    </measure>
-    <!--=======================================================-->
-    <measure number="10">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-    </measure>
-    <!--=======================================================-->
-    <measure number="11">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-    </measure>
-    <!--=======================================================-->
-    <measure number="12">
-      <print new-system="yes"/>
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-    </measure>
-    <!--=======================================================-->
-    <measure number="13">
-      <note>
-        <rest/>
-        <duration>4</duration>
-        <voice>1</voice>
-      </note>
-      <barline location="right">
-        <bar-style>light-heavy</bar-style>
-      </barline>
-    </measure>
-  </part>
-  <!--=========================================================-->
-</score-partwise>
diff --git a/input/regression/musicxml/09b-RepeatWithAlternatives-Finale.xml b/input/regression/musicxml/09b-RepeatWithAlternatives-Finale.xml
new file mode 100644 (file)
index 0000000..23b0212
--- /dev/null
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+  <identification>\r
+    <encoding>\r
+      <software>Finale 2007 for Windows</software>\r
+      <software>Dolet Light for Finale 2007</software>\r
+      <encoding-date>2007-10-17</encoding-date>\r
+    </encoding>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+      <score-instrument id="P1-I1">\r
+        <instrument-name>Grand Piano</instrument-name>\r
+      </score-instrument>\r
+      <midi-instrument id="P1-I1">\r
+        <midi-channel>1</midi-channel>\r
+        <midi-program>1</midi-program>\r
+      </midi-instrument>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <sound tempo="120"/>\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+        <type>whole</type>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="2">\r
+      <barline location="left">\r
+        <ending number="1" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+        <type>whole</type>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <ending number="1" type="stop"/>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="3">\r
+      <barline location="left">\r
+        <ending number="2" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+        <type>whole</type>\r
+      </note>\r
+      <barline location="right">\r
+        <ending number="2" type="discontinue"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="4">\r
+      <note>\r
+        <pitch>\r
+          <step>C</step>\r
+          <octave>5</octave>\r
+        </pitch>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+        <type>whole</type>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
diff --git a/input/regression/musicxml/09c-Barlines-Finale.xml b/input/regression/musicxml/09c-Barlines-Finale.xml
new file mode 100644 (file)
index 0000000..611760a
--- /dev/null
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+  <movement-title>Barline test</movement-title>\r
+  <identification>\r
+    <creator type="composer">Reinhold Kainhofer</creator>\r
+    <rights>Public Domain</rights>\r
+    <encoding>\r
+      <software>Finale 2007 for Windows</software>\r
+      <software>Dolet Light for Finale 2007</software>\r
+      <encoding-date>2007-09-21</encoding-date>\r
+    </encoding>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+      <score-instrument id="P1-I1">\r
+        <instrument-name>Grand Piano</instrument-name>\r
+      </score-instrument>\r
+      <midi-instrument id="P1-I1">\r
+        <midi-channel>1</midi-channel>\r
+        <midi-program>1</midi-program>\r
+      </midi-instrument>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <sound tempo="120"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-light</bar-style>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="2">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="3">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="4">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>dashed</bar-style>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="5">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>dotted</bar-style>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="6">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>none</bar-style>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="7">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="8">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="9">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="10">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="11">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="12">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="13">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
diff --git a/input/regression/musicxml/09d-RepeatMultipleTimes-Finale.xml b/input/regression/musicxml/09d-RepeatMultipleTimes-Finale.xml
new file mode 100644 (file)
index 0000000..6cbe6db
--- /dev/null
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+  <identification>\r
+    <encoding>\r
+      <software>Finale 2007 for Windows</software>\r
+      <software>Dolet Light for Finale 2007</software>\r
+      <encoding-date>2007-10-19</encoding-date>\r
+    </encoding>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+      <score-instrument id="P1-I1">\r
+        <instrument-name>Grand Piano</instrument-name>\r
+      </score-instrument>\r
+      <midi-instrument id="P1-I1">\r
+        <midi-channel>1</midi-channel>\r
+        <midi-program>1</midi-program>\r
+      </midi-instrument>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <sound tempo="120"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="2">\r
+      <barline location="left">\r
+        <bar-style>heavy-light</bar-style>\r
+        <repeat direction="forward"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="3">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <repeat direction="backward" times="5"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="4">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="5">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="6">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="7">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <repeat direction="backward" times="3"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="8">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
diff --git a/input/regression/musicxml/09e-Alternatives-Finale.xml b/input/regression/musicxml/09e-Alternatives-Finale.xml
new file mode 100644 (file)
index 0000000..dbbb9d4
--- /dev/null
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+  <movement-title>Alternatives Test</movement-title>\r
+  <identification>\r
+    <encoding>\r
+      <software>Finale 2007 for Windows</software>\r
+      <software>Dolet Light for Finale 2007</software>\r
+      <encoding-date>2007-10-15</encoding-date>\r
+    </encoding>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+      <score-instrument id="P1-I1">\r
+        <instrument-name>Grand Piano</instrument-name>\r
+      </score-instrument>\r
+      <midi-instrument id="P1-I1">\r
+        <midi-channel>1</midi-channel>\r
+        <midi-program>1</midi-program>\r
+      </midi-instrument>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <sound tempo="120"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="2">\r
+      <barline location="left">\r
+        <ending number="1" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <ending number="1" type="stop"/>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="3">\r
+      <barline location="left">\r
+        <ending number="2" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="4">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="5">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <ending number="2" type="stop"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="6">\r
+      <barline location="left">\r
+        <ending number="3" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <ending number="3" type="discontinue"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="7">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="8">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="9">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="10">\r
+      <barline location="left">\r
+        <ending number="1" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <ending number="1" type="stop"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="11">\r
+      <barline location="left">\r
+        <ending number="5" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <ending number="5" type="stop"/>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="12">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
diff --git a/input/regression/musicxml/09f-Repeats-Finale.xml b/input/regression/musicxml/09f-Repeats-Finale.xml
new file mode 100644 (file)
index 0000000..ec5bb43
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+  <movement-title>Finale Repeat test</movement-title>\r
+  <identification>\r
+    <creator type="composer">Reinhold Kainhofer</creator>\r
+    <rights>Public Domain</rights>\r
+    <encoding>\r
+      <software>Finale 2007 for Windows</software>\r
+      <software>Dolet Light for Finale 2007</software>\r
+      <encoding-date>2007-08-31</encoding-date>\r
+    </encoding>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+      <score-instrument id="P1-I1">\r
+        <instrument-name>Grand Piano</instrument-name>\r
+      </score-instrument>\r
+      <midi-instrument id="P1-I1">\r
+        <midi-channel>1</midi-channel>\r
+        <midi-program>1</midi-program>\r
+      </midi-instrument>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <sound tempo="120"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="2">\r
+      <barline location="left">\r
+        <ending number="1" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <ending number="1" type="stop"/>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="3">\r
+      <barline location="left">\r
+        <ending number="2" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <ending number="2" type="discontinue"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="4">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="5">\r
+      <barline location="left">\r
+        <bar-style>heavy-light</bar-style>\r
+        <repeat direction="forward"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="6">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="7">\r
+      <print new-system="yes"/>\r
+      <barline location="left">\r
+        <ending number="1" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <ending number="1" type="stop"/>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="8">\r
+      <barline location="left">\r
+        <bar-style>heavy-light</bar-style>\r
+        <repeat direction="forward"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="9">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="10">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
diff --git a/input/regression/musicxml/09g-Endings-Finale.xml b/input/regression/musicxml/09g-Endings-Finale.xml
new file mode 100644 (file)
index 0000000..82b4c55
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 1.0 Partwise//EN"\r
+                                "http://www.musicxml.org/dtds/partwise.dtd">\r
+<score-partwise>\r
+  <identification>\r
+    <encoding>\r
+      <software>Finale 2007 for Windows</software>\r
+      <software>Dolet Light for Finale 2007</software>\r
+      <encoding-date>2007-10-13</encoding-date>\r
+    </encoding>\r
+  </identification>\r
+  <part-list>\r
+    <score-part id="P1">\r
+      <part-name>MusicXML Part</part-name>\r
+      <score-instrument id="P1-I1">\r
+        <instrument-name>Grand Piano</instrument-name>\r
+      </score-instrument>\r
+      <midi-instrument id="P1-I1">\r
+        <midi-channel>1</midi-channel>\r
+        <midi-program>1</midi-program>\r
+      </midi-instrument>\r
+    </score-part>\r
+  </part-list>\r
+  <!--=========================================================-->\r
+  <part id="P1">\r
+    <measure number="1">\r
+      <attributes>\r
+        <divisions>1</divisions>\r
+        <key>\r
+          <fifths>0</fifths>\r
+          <mode>major</mode>\r
+        </key>\r
+        <time symbol="common">\r
+          <beats>4</beats>\r
+          <beat-type>4</beat-type>\r
+        </time>\r
+        <clef>\r
+          <sign>G</sign>\r
+          <line>2</line>\r
+        </clef>\r
+      </attributes>\r
+      <sound tempo="120"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="2">\r
+      <barline location="left">\r
+        <ending number="1, 2, 3" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <ending number="1, 2, 3" type="stop"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="3">\r
+      <barline location="left">\r
+        <ending number="2" type="start"/>\r
+      </barline>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <ending number="2" type="discontinue"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="4">\r
+      <print new-system="yes"/>\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+        <ending number="2" type="stop"/>\r
+        <repeat direction="backward"/>\r
+      </barline>\r
+    </measure>\r
+    <!--=======================================================-->\r
+    <measure number="5">\r
+      <note>\r
+        <rest/>\r
+        <duration>4</duration>\r
+        <voice>1</voice>\r
+      </note>\r
+      <barline location="right">\r
+        <bar-style>light-heavy</bar-style>\r
+      </barline>\r
+    </measure>\r
+  </part>\r
+  <!--=========================================================-->\r
+</score-partwise>\r
index ec647d85079d052b9ae5b3de558105274d6a75cc..53ecd0eca35432d8101ea9f485b2bef414a288f5 100644 (file)
@@ -4,5 +4,5 @@ STEPMAKE_TEMPLATES=documentation texinfo tex
 LOCALSTEPMAKE_TEMPLATES=lilypond ly lysdoc musicxml
 
 include $(depth)/make/stepmake.make
-TITLE=Lilypon musicxml2ly Regression Tests
+TITLE=Lilypond musicxml2ly Regression Tests
 
index a78885dd3c6453eeeceb6e06fa7dafca273fb908..369542226fc21dc9242f3ecdcac70ba0bc1a1f67 100644 (file)
@@ -416,7 +416,7 @@ class SequentialMusic (NestedMusic):
         at = len( self.elements ) - 1
         while (at >= 0 and
                not isinstance (self.elements[at], EventChord) and
-               not isinstance (self.elements[at], BarCheck)):
+               not isinstance (self.elements[at], BarLine)):
             at -= 1
 
         if (at >= 0 and isinstance (self.elements[at], EventChord)):
@@ -450,6 +450,36 @@ class SequentialMusic (NestedMusic):
             e.set_start (start)
             start += e.get_length()
 
+class RepeatedMusic:
+    def __init__ (self):
+        self.repeat_type = "volta"
+        self.repeat_count = 2
+        self.endings = []
+        self.music = None
+    def set_music (self, music):
+        if isinstance (music, Music):
+            self.music = music
+        elif isinstance (music, list):
+            self.music = SequentialMusic ()
+            self.music.elements = music
+        else:
+            sys.stderr.write ("WARNING: Unable to set the music %s for the repeat %s" % (music, self))
+    def add_ending (self, music):
+        self.endings.append (music)
+    def print_ly (self, printer):
+        printer.dump ('\\repeat %s %s' % (self.repeat_type, self.repeat_count))
+        if self.music:
+            self.music.print_ly (printer)
+        else:
+            sys.stderr.write ("WARNING: Encountered repeat without body\n")
+            printer.dump ('{}')
+        if self.endings:
+            printer.dump ('\\alternative {')
+            for e in self.endings:
+                e.print_ly (printer)
+            printer.dump ('}')
+
+
 class Lyrics:
     def __init__ (self):
         self.lyrics_syllables = []
@@ -548,20 +578,27 @@ class Partial (Music):
         if self.partial:
             printer.dump ("\\partial %s" % self.partial.ly_expression ())
 
-class BarCheck (Music):
+class BarLine (Music):
     def __init__ (self):
         Music.__init__ (self)
         self.bar_number = 0
+        self.type = None
         
     def print_ly (self, printer):
+        bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': ":",
+                       'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
+                       'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'",
+                       'short': "'", 'none': "" }.get (self.type, None)
+        if bar_symbol <> None:
+            printer.dump ('\\bar "%s"' % bar_symbol)
+        else:
+            printer.dump ("|")
+
         if self.bar_number > 0 and (self.bar_number % 10) == 0:
-            printer.dump ("|  \\barNumberCheck #%d " % self.bar_number)
-            printer.newline ()
+            printer.dump ("\\barNumberCheck #%d " % self.bar_number)
         else:
-            printer.dump ("| ")
             printer.print_verbatim (' %% %d' % self.bar_number)
-            printer.newline ()
+        printer.newline ()
 
     def ly_expression (self):
         return " | "
index 9a5d43eeec74e4520f36de7b44e92c41a479d5f2..81d2e82465a744814f6c56e728233dfc7cbd3a8d 100644 (file)
@@ -270,7 +270,11 @@ class Attributes (Measure_element):
 
         fifths = int (key.get_maybe_exist_named_child ('fifths').get_text ())
         return (fifths, mode)
-                
+
+class Barline (Measure_element):
+    pass
+class BarStyle (Music_xml_node):
+    pass
 class Partial (Measure_element):
     def __init__ (self, partial):
         Measure_element.__init__ (self)
@@ -604,7 +608,9 @@ class Part (Music_xml_node):
        for n in elements:
            voice_id = n.get_maybe_exist_typed_child (get_class ('voice'))
 
-           if not (voice_id or isinstance (n, Attributes) or isinstance (n, Direction) or isinstance (n, Partial) ):
+           if not (voice_id or isinstance (n, Attributes) or
+                    isinstance (n, Direction) or isinstance (n, Partial) or
+                    isinstance (n, Barline) ):
                continue
 
            if isinstance (n, Attributes) and not start_attr:
@@ -619,7 +625,7 @@ class Part (Music_xml_node):
                         voices[v].add_element (staff_attributes)
                 continue
 
-            if isinstance (n, Partial):
+            if isinstance (n, Partial) or isinstance (n, Barline):
                 for v in voices.keys ():
                     voices[v].add_element (n)
                 continue
@@ -784,6 +790,8 @@ class_dict = {
         '#text': Hash_text,
        'accidental': Accidental,
        'attributes': Attributes,
+        'barline': Barline,
+        'bar-style': BarStyle,
        'beam' : Beam,
         'bend' : Bend,
        'chord': Chord,
index ba841e0d00bd1fa73e238d7762b1e201b4b360cc..26ee3e4abf1332c3a1239af4245edb1ab3948f45 100644 (file)
@@ -173,6 +173,92 @@ def musicxml_partial_to_lily (partial_len):
     else:
         return Null
 
+# Detect repeats and alternative endings in the chord event list (music_list)
+# and convert them to the corresponding musicexp objects, containing nested
+# music
+def group_repeats (music_list):
+    repeat_replaced = True
+    music_start = 0
+    i=0
+    # Walk through the list of expressions, looking for repeat structure
+    # (repeat start/end, corresponding endings). If we find one, try to find the
+    # last event of the repeat, replace the whole structure and start over again.
+    # For nested repeats, as soon as we encounter another starting repeat bar,
+    # treat that one first, and start over for the outer repeat.
+    while repeat_replaced and i<10:
+        i += 1
+        repeat_start = -1  # position of repeat start / end
+        repeat_end = -1 # position of repeat start / end
+        repeat_times = 0
+        ending_start = -1 # position of current ending start
+        endings = [] # list of already finished endings
+        pos = 0
+        repeat_replaced = False
+        final_marker = 0
+        while pos < len (music_list) and not repeat_replaced:
+            e = music_list[pos]
+            repeat_finished = False
+            if isinstance (e, RepeatMarker):
+                if not repeat_times and e.times:
+                    repeat_times = e.times
+                if e.direction == -1:
+                    if repeat_end >= 0:
+                        repeat_finished = True
+                    else:
+                        repeat_start = pos
+                        repeat_end = -1
+                        ending_start = -1
+                        endings = []
+                elif e.direction == 1:
+                    if repeat_start < 0:
+                        repeat_start = 0
+                    if repeat_end < 0:
+                        repeat_end = pos
+                    final_marker = pos
+            elif isinstance (e, EndingMarker):
+                if e.direction == -1:
+                    if repeat_start < 0:
+                        repeat_start = 0
+                        repeat_end = pos
+                    ending_start = pos
+                elif e.direction == 1:
+                    if ending_start < 0:
+                        ending_start = 0
+                    endings.append ([ending_start, pos])
+                    ending_start = -1
+                    final_marker = pos
+            elif not isinstance (e, musicexp.BarLine):
+                # As soon as we encounter an element when repeat start and end
+                # is set and we are not inside an alternative ending,
+                # this whole repeat structure is finished => replace it
+                if repeat_start >= 0 and repeat_end > 0 and ending_start < 0:
+                    repeat_finished = True
+
+            if repeat_finished:
+                # We found the whole structure replace it!
+                r = musicexp.RepeatedMusic ()
+                if repeat_times <= 0:
+                    repeat_times = 2
+                r.repeat_count = repeat_times
+                # don't erase the first element for "implicit" repeats (i.e. no
+                # starting repeat bars at the very beginning)
+                start = repeat_start+1
+                if repeat_start == music_start:
+                    start = music_start
+                r.set_music (music_list[start:repeat_end])
+                for (start, end) in endings:
+                    s = musicexp.SequentialMusic ()
+                    s.elements = music_list[start+1:end]
+                    r.add_ending (s)
+                del music_list[repeat_start:final_marker+1]
+                music_list.insert (repeat_start, r)
+                repeat_replaced = True
+            pos += 1
+        # TODO: Implement repeats until the end without explicit ending bar
+    return music_list
+
+
+
 def group_tuplets (music_list, events):
 
 
@@ -274,6 +360,71 @@ def musicxml_attributes_to_lily (attrs):
     
     return elts
 
+class Marker (musicexp.Music):
+    def __init__ (self):
+        self.direction = 0
+        self.event = None
+    def print_ly (self, printer):
+        sys.stderr.write ("Encountered unprocessed marker %s\n" % self)
+        pass
+    def ly_expression (self):
+        return ""
+class RepeatMarker (Marker):
+    def __init__ (self):
+        Marker.__init__ (self)
+        self.times = 0
+class EndingMarker (Marker):
+    pass
+
+# Convert the <barline> element to musicxml.BarLine (for non-standard barlines)
+# and to RepeatMarker and EndingMarker objects for repeat and
+# alternatives start/stops
+def musicxml_barline_to_lily (barline):
+    # retval contains all possible markers in the order:
+    # 0..bw_ending, 1..bw_repeat, 2..barline, 3..fw_repeat, 4..fw_ending
+    retval = {}
+    bartype_element = barline.get_maybe_exist_named_child ("bar-style")
+    repeat_element = barline.get_maybe_exist_named_child ("repeat")
+    ending_element = barline.get_maybe_exist_named_child ("ending")
+
+    bartype = None
+    if bartype_element:
+        bartype = bartype_element.get_text ()
+
+    if repeat_element and hasattr (repeat_element, 'direction'):
+        repeat = RepeatMarker ()
+        repeat.direction = {"forward": -1, "backward": 1}.get (repeat_element.direction, 0)
+
+        if ( (repeat_element.direction == "forward" and bartype == "heavy-light") or
+             (repeat_element.direction == "backward" and bartype == "light-heavy") ):
+            bartype = None
+        if hasattr (repeat_element, 'times'):
+            try:
+                repeat.times = int (repeat_element.times)
+            except ValueError:
+                repeat.times = 2
+        repeat.event = barline
+        if repeat.direction == -1:
+            retval[1] = repeat
+        else:
+            retval[3] = repeat
+
+    if ending_element and hasattr (ending_element, 'type'):
+        ending = EndingMarker ()
+        ending.direction = {"start": -1, "stop": 1, "discontinue": 1}.get (ending_element.type, 0)
+        ending.event = barline
+        if ending.direction == -1:
+            retval[0] = ending
+        else:
+            retval[4] = ending
+
+    if bartype:
+        b = musicexp.BarLine ()
+        b.type = bartype
+        retval[2] = b
+
+    return retval.values ()
+
 spanner_event_dict = {
     'slur' : musicexp.SlurEvent,
     'beam' : musicexp.BeamEvent,
@@ -597,6 +748,9 @@ class LilyPondVoiceBuilder:
         if self.pending_multibar > Rational (0):
             self._insert_multibar ()
         self.elements.append (command)
+    def add_barline (self, barline):
+        # TODO: Implement merging of default barline and custom bar line
+        self.add_music (barline, Rational (0))
     def add_partial (self, command):
         self.ignore_skips = True
         self.add_command (command)
@@ -606,9 +760,9 @@ class LilyPondVoiceBuilder:
         self.pending_dynamics.append (dynamic)
 
     def add_bar_check (self, number):
-        b = musicexp.BarCheck ()
+        b = musicexp.BarLine ()
         b.bar_number = number
-        self.add_command (b)
+        self.add_barline (b)
 
     def jumpto (self, moment):
         current_end = self.end_moment + self.pending_multibar
@@ -638,7 +792,7 @@ class LilyPondVoiceBuilder:
         at = len( self.elements ) - 1
         while (at >= 0 and
                not isinstance (self.elements[at], musicexp.EventChord) and
-               not isinstance (self.elements[at], musicexp.BarCheck)):
+               not isinstance (self.elements[at], musicexp.BarLine)):
             at -= 1
 
         if (self.elements
@@ -703,11 +857,20 @@ def musicxml_voice_to_lily_voice (voice):
                     number = 0
                 if number > 0:
                     voice_builder.add_bar_check (number)
-                
+
             for a in musicxml_attributes_to_lily (n):
                 voice_builder.add_command (a)
             continue
 
+        if isinstance (n, musicxml.Barline):
+            barlines = musicxml_barline_to_lily (n)
+            for a in barlines:
+                if isinstance (a, musicexp.BarLine):
+                    voice_builder.add_barline (a)
+                elif isinstance (a, RepeatMarker) or isinstance (a, EndingMarker):
+                    voice_builder.add_command (a)
+            continue
+
         if not n.__class__.__name__ == 'Note':
             error_message ('not a Note or Attributes? %s' % n)
             continue
@@ -887,6 +1050,7 @@ def musicxml_voice_to_lily_voice (voice):
     voice_builder.add_music (musicexp.EventChord (), Rational (0))
     
     ly_voice = group_tuplets (voice_builder.elements, tuplet_events)
+    ly_voice = group_repeats (ly_voice)
 
     seq_music = musicexp.SequentialMusic ()