joerg 2003/08/16 07:37:07
Modified: . status.xml
src/blocks/midi/samples samples.xml sitemap.xmap
src/blocks/midi/java/org/apache/cocoon/serialization
XMidiSerializer.java
Added: src/blocks/midi/samples/stylesheets transpose.xsl
retrograde.xsl invert.xsl
src/blocks/midi/resources cocoon.sib
Removed: src/blocks/midi/samples/xmidi cocoon.xmi prelude.xmi
src/blocks/midi/samples/midi cocoon
Log:
Patch 22479 applied: added transition and inversion to the midi block (thanks to
Marc Leicester).
Revision Changes Path
1.124 +5 -1 cocoon-2.1/status.xml
Index: status.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/status.xml,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -r1.123 -r1.124
--- status.xml 16 Aug 2003 13:30:03 -0000 1.123
+++ status.xml 16 Aug 2003 14:37:06 -0000 1.124
@@ -189,6 +189,10 @@
<changes>
<release version="@version@" date="@date@">
+ <action dev="JH" type="update" fixes-bug="22479"
+ due-to="Mark Leicester" due-to-email="[EMAIL PROTECTED]">
+ Midi block: added transposition and inversion stylesheets and samples.
+ </action>
<action dev="SW" type="fix">
Rewrite handling of internal-redirects (i.e. redirects to "cocoon:" URLs).
Previously, internal redirects
where not handled for internal requests (i.e. sitemap source). This bug
prevented among other cases the use
1.1 cocoon-2.1/src/blocks/midi/samples/stylesheets/transpose.xsl
Index: transpose.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="transposition" select="0"/>
<xsl:template match="NOTE_ON">
<xsl:variable name="fixedTransposition">
<xsl:choose>
<xsl:when test="not(number($transposition) = number($transposition))">
<xsl:message>The parameter $transposition must be a number!</xsl:message>
<xsl:text>0</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$transposition"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="offset" select="$fixedTransposition"/>
<NOTE_ON PITCH="[EMAIL PROTECTED] + $offset}" REGISTER="[EMAIL PROTECTED]"
VELOCITY="[EMAIL PROTECTED]">
<xsl:apply-templates/>
</NOTE_ON>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
1.1 cocoon-2.1/src/blocks/midi/samples/stylesheets/retrograde.xsl
Index: retrograde.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="MTrk">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:variable name="deltas" select="DELTA[descendant::NOTE_ON]"/>
<xsl:variable name="deltaCount" select="count($deltas)"/>
<xsl:comment>Count: <xsl:value-of select="$deltaCount"/></xsl:comment>
<xsl:for-each select="DELTA">
<xsl:choose>
<xsl:when test="descendant::NOTE_ON">
<xsl:variable name="position"
select="count(preceding-sibling::DELTA[descendant::NOTE_ON]) + 1"/>
<xsl:variable name="newPosition" select="($deltaCount -
$position) + 1"/>
<xsl:comment>Position: <xsl:value-of select="$position"/>, New:
<xsl:value-of select="$newPosition"/></xsl:comment>
<xsl:copy>
<xsl:variable name="followingDelta"
select="following-sibling::DELTA[descendant::NOTE_ON]"/>
<xsl:attribute name="DTIME">
<xsl:choose>
<xsl:when test="$position = 1">00000000</xsl:when>
<xsl:when test="$followingDelta">
<xsl:value-of select="$followingDelta/@DTIME"/>
</xsl:when>
<xsl:otherwise>00000000</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:comment>The DTIME was <xsl:value-of select="@DTIME"/>, and
is <xsl:value-of select="$followingDelta/@DTIME"/></xsl:comment>
<xsl:copy-of select="$deltas[$newPosition]/*"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
1.1 cocoon-2.1/src/blocks/midi/samples/stylesheets/invert.xsl
Index: invert.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="NOTE_ON">
<xsl:variable name="notes" select="//NOTE_ON"/>
<xsl:variable name="medianPitch" select="floor(sum($notes/@PITCH) div
count($notes))"/>
<NOTE_ON PITCH="{$medianPitch - (@PITCH - $medianPitch)}" REGISTER="[EMAIL
PROTECTED]" VELOCITY="[EMAIL PROTECTED]">
<xsl:apply-templates />
</NOTE_ON>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
1.3 +44 -18 cocoon-2.1/src/blocks/midi/samples/samples.xml
Index: samples.xml
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/midi/samples/samples.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- samples.xml 11 Aug 2003 21:54:09 -0000 1.2
+++ samples.xml 16 Aug 2003 14:37:07 -0000 1.3
@@ -3,41 +3,67 @@
<sample name="Back" href="..">to Cocoon examples main page</sample>
</group>
<group name="What is the MIDI block?">
- <note>The MIDI block currently gives you a component (the XMidiGenerator)
- to generate an XML representation from any MIDI file (called XMidi by its
- author Peter Loeb). There is also a component (the XMidiSerializer) to
- render XMidi back as a MIDI file. In due course I will add some
- transformers to perform basic musical manipulations such as transposition,
- inversion and retrograde. Hopefully I shall also add some transformers to
- generate SVG visualisations of the XMidi, starting with normal western
- musical notation.</note>
+ <note>The MIDI block currently gives you an XMidiGenerator to generate an
+ XML representation of any MIDI file (called XMidi by its author Peter
+ Loeb). There is also the XMidiSerializer to render XMidi back as a MIDI
+ file. I have used XSLT to provide some basic musical manipulations such as
+ transposition, and inversion. Retrograde is harder, but I shall see what I
+ can come up with. Hopefully I shall also add some transformers to generate
+ SVG visualisations of the XMidi, starting with normal western musical
+ notation.</note>
<sample name="MIDI Documentation"
href="http://wiki.cocoondev.org/Wiki.jsp?page=MIDI">Documentation available
on the Cocoon Wiki.</sample>
</group>
<group name="A Cocoon signature tune">
- <sample name="A Short MIDI File" href="raw/cocoon.mid">This is a little
- ditty I wrote on the notes you get if you take the letters of the word
- "Cocoon" (using A=A, B=B, ... G=G, H=A, I=B etc.) You get C-A-C-A-A-G: very
+ <sample name="A Short MIDI File" href="cocoon.mid">This is a little ditty I
+ wrote on the notes you get if you take the letters of the word "Cocoon"
+ (using A=A, B=B, ... G=G, H=A, I=B etc.) You get C-A-C-A-A-G: very
catchy.</sample>
<sample name="The XMidi Generator" href="cocoon.xmi">The previous file
rendered as XMidi, using the XMidiGenerator.</sample>
- <sample name="The XMidi Serializer" href="cocoon.mid">The XMidi output of
- the previous pipeline rendered again as MIDI, using the
+ <sample name="The XMidi Serializer" href="xmidi/cocoon.mid">The XMidi
+ output of the previous pipeline rendered again as MIDI, using the
XMidiSerializer.</sample>
</group>
<group name="Bach's Prelude No.1 in C, BWV846a">
- <sample name="A Longer MIDI File" href="raw/prelude.mid">Bach's Prelude
- No.1 in C, BWV846a , sequenced by B.R.Guillaud and available from The
- Classical Music Archives (see below).</sample>
+ <sample name="A Longer MIDI File" href="prelude.mid">Bach's Prelude No.1 in
+ C, BWV846a , sequenced by B.R.Guillaud and available from The Classical
+ Music Archives (see below).</sample>
<sample name="The XMidi Generator" href="prelude.xmi">The previous file
rendered as XMidi, using the XMidiGenerator. Be warned, your browser may
take some time to render the XML. As the emperor of Austria supposedly said
to Mozart, "Too many notes!"</sample>
- <sample name="The XMidi Serializer" href="prelude.mid">The XMidi output of
- the previous pipeline rendered again as MIDI, using the
+ <sample name="The XMidi Serializer" href="xmidi/prelude.mid">The XMidi
+ output of the previous pipeline rendered again as MIDI, using the
XMidiSerializer.</sample>
</group>
+ <group name="Transposition">
+ <sample name="A Cocoon signature tune"
+ href="transposed/cocoon.mid?transposition=-24">You sing bass? Want it
+ lower?</sample>
+ <sample name="Bach's Prelude No.1 in C#, BWV846a +1"
+ href="transposed/prelude.mid?transposition=+1">Transposing Bach with XSLT.
+ What next?</sample>
+ <sample name="Bach's Prelude No.1 ad absurdum, BWV846a +24"
+ href="transposed/prelude.mid?transposition=+24">Bach that only dogs can
+ hear.</sample>
+ </group>
+ <group name="Inversion">
+ <sample name="A Cocoon signature tune" href="inverted/cocoon.mid">Upside
+ down "Cocoon"? Sure is. I haven't worked out what this spells.</sample>
+ <sample name="Bach's Prelude No.1 in C, BWV846a"
+ href="inverted/prelude.mid">This is our familiar prelude turned on its
+ head. As Schoenberg said, this hat is still a [beautiful] hat whichever way
+ you look at it.</sample>
+ </group>
+<!--
+ <group name="Retrograde">
+ <sample name="enut erutangis noocoC A" href="reversed/cocoon.mid">.</sample>
+ <sample name="a648VWB ,C ni 1.oN edulerP s'hcaB"
+ href="reversed/prelude.mid">Every which way.</sample>
+ </group>
+ -->
<group name="Reference">
<sample name="The Original XMidi Home Page"
href="http://www.palserv.com/XMidi/">This is the origin of a lot of the
1.4 +34 -10 cocoon-2.1/src/blocks/midi/samples/sitemap.xmap
Index: sitemap.xmap
===================================================================
RCS file: /home/cvs/cocoon-2.1/src/blocks/midi/samples/sitemap.xmap,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- sitemap.xmap 11 Aug 2003 23:17:36 -0000 1.3
+++ sitemap.xmap 16 Aug 2003 14:37:07 -0000 1.4
@@ -6,6 +6,7 @@
<map:generators default="file">
<map:generator name="xmidi" src="org.apache.cocoon.generation.XMidiGenerator"
logger="midi.sitemap.generator"/>
</map:generators>
+ <map:transformers default="xslt"/>
<map:serializers default="html">
<map:serializer name="xmidi"
src="org.apache.cocoon.serialization.XMidiSerializer"
logger="midi.sitemap.serializer"/>
</map:serializers>
@@ -14,10 +15,7 @@
<!-- =========================== Views =================================== -->
<map:views>
- <map:view name="debug" from-label="debug">
- <map:serialize type="xml"/>
- </map:view>
- <map:view name="xml" from-label="xml">
+ <map:view name="xmi" from-label="xmi">
<map:serialize type="xml"/>
</map:view>
</map:views>
@@ -35,22 +33,48 @@
<map:serialize/>
</map:match>
- <map:match pattern="raw/*.mid">
+ <map:match pattern="*.mid">
<map:read src="midi/{1}.mid" mime-type="audio/x-midi"/>
</map:match>
+
+ <map:match pattern="*.xmi">
+ <map:generate type="xmidi" src="midi/{1}.mid"/>
+ <map:serialize type="xml"/>
+ </map:match>
- <map:match pattern="*.mid">
+ <map:match pattern="xmidi/*.mid">
+ <map:generate type="xmidi" src="midi/{1}.mid" label="xmi"/>
+ <map:serialize type="xmidi"/>
+ </map:match>
+
+ <map:match pattern="transposed/*.mid">
<map:generate type="xmidi" src="midi/{1}.mid"/>
+ <map:transform type="xslt" src="stylesheets/transpose.xsl" label="xmi">
+ <map:parameter name="transposition"
value="{request-param:transposition}"/>
+ </map:transform>
<map:serialize type="xmidi"/>
</map:match>
-
- <map:match pattern="*.xmi">
+
+ <map:match pattern="inverted/*.mid">
<map:generate type="xmidi" src="midi/{1}.mid"/>
- <map:serialize type="xml"/>
+ <map:transform type="xslt" src="stylesheets/invert.xsl" label="xmi"/>
+ <map:serialize type="xmidi"/>
</map:match>
-
+ <!--
+ <map:match pattern="reversed/*.mid">
+ <map:generate type="xmidi" src="midi/{1}.mid"/>
+ <map:transform type="xslt" src="stylesheets/retrograde.xsl"
label="xmi"/>
+ <map:serialize type="xmidi"/>
+ </map:match>
+ -->
</map:pipeline>
</map:pipelines>
</map:sitemap>
+
+
+
+
+
+
1.3 +1 -116
cocoon-2.1/src/blocks/midi/java/org/apache/cocoon/serialization/XMidiSerializer.java
Index: XMidiSerializer.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/midi/java/org/apache/cocoon/serialization/XMidiSerializer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- XMidiSerializer.java 11 Aug 2003 23:17:36 -0000 1.2
+++ XMidiSerializer.java 16 Aug 2003 14:37:07 -0000 1.3
@@ -556,122 +556,7 @@
throw new SAXException(e);
}
}
- /*
- void processElement()
- {
- String parent = xe.getParentNode().getNodeName();
- if (xe.getNodeType() == Node.ELEMENT_NODE)
- {
- Element elem = (Element) xe;
- localName = elem.getTagName();
-
-
- if (xe.getNodeType() == Node.TEXT_NODE)
- {
-
- if (parent.equals("FORMAT"))
- {
- if (!chunkFlag)
- {
- throw new ProcessingException("FORMAT element only valid within a
chunk");
- }
- if (!chunkType.equals("MThd"))
- {
- throw new ProcessingException("FORMAT element must be in MThd chunk");
- }
- String typ = xe.getNodeValue();
- if (typ == null)
- {
- throw new ProcessingException("null value for MThd->FORMAT");
- }
- typ = typ.trim();
- if (typ == null)
- {
- throw new ProcessingException("null value for MThd->FORMAT (after
trim)");
- }
- for (int i = 0; i < typ.length(); i++)
- {
- if (typ.substring(i, i + 1).compareTo("0")
- < 0 | typ.substring(i, i + 1).compareTo("9")
- > 0)
- {
- throw new ProcessingException(
- "invalid numeric midi format: " + typ);
- }
- }
- this.getLogger().debug(
- "chunk->format is " + typ + " (parent is " + parent + ")");
- midiFormat = Utils.stringToInt(typ);
- writeHalfWord(midiFormat);
- }
-
- if (parent.equals("TRACKS"))
- {
- if (!chunkFlag)
- {
- throw new ProcessingException("TRACKS element only valid within a
chunk");
- }
- if (!chunkType.equals("MThd"))
- {
- throw new ProcessingException("TRACKS element must be in MThd chunk");
- }
- String sNum = xe.getNodeValue();
- if (sNum == null)
- {
- throw new ProcessingException("null value for MThd->TRACKS");
- }
- sNum = sNum.trim();
- if (sNum == null)
- {
- throw new ProcessingException("null value for MThd->TRACKS (after
trim)");
- }
- this.getLogger().debug("chunk->tracks is " + sNum);
- Integer iNum = new Integer(sNum);
- numTracks = iNum.intValue();
- writeHalfWord(numTracks);
- }
-
- if (parent.equals("PPNQ"))
- {
- if (!chunkFlag)
- {
- throw new ProcessingException("PPNQ element only valid within a chunk");
- }
- if (!chunkType.equals("MThd"))
- {
- throw new ProcessingException("PPNQ element must be in MThd chunk");
- }
- String pnq = xe.getNodeValue();
- if (pnq == null)
- {
- throw new ProcessingException("null value for MThd->PPNQ");
- }
- pnq = pnq.trim();
- if (pnq == null)
- {
- throw new ProcessingException("null value for MThd->PPNQ (after trim)");
- }
- this.getLogger().debug("chunk->ppnq is " + pnq);
- writeHex(pnq, 2);
- }
-
- if (parent.equals("HEXDATA"))
- {
- if (!chunkFlag)
- {
- throw new ProcessingException("HEXDATA element only valid within
CHUNK");
- }
- String xdata = xe.getNodeValue();
- if (xdata == null)
- {
- throw new ProcessingException("null value for CHUNK->HEXDATA");
- }
- writeHex(xdata, chunkLen);
- }
-
- }
- }
- */
+
void writeString(String s, int len) throws IOException, ProcessingException
{
int l = s.length();
1.1 cocoon-2.1/src/blocks/midi/resources/cocoon.sib
<<Binary file>>