summaryrefslogtreecommitdiff
path: root/doc/html/index.html
diff options
context:
space:
mode:
authorGary Scavone <gary@music.mcgill.ca>2013-10-11 15:15:25 +0200
committerStephen Sinclair <sinclair@music.mcgill.ca>2013-10-11 15:15:25 +0200
commit4ef34bb4fd4e53cbfbc9dc1c0604ec55972c11ff (patch)
treee12dc3b69292363e9ff17f1fbc3a36a6039a32fe /doc/html/index.html
parent094136eeafabac952b3bc370c75804d912437c82 (diff)
Release 1.0.8 tarball1.0.8
Diffstat (limited to 'doc/html/index.html')
-rw-r--r--doc/html/index.html150
1 files changed, 82 insertions, 68 deletions
diff --git a/doc/html/index.html b/doc/html/index.html
index 1eadaa1..8dd1545 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -7,12 +7,13 @@
<CENTER>
<a class="qindex" href="index.html">Tutorial</a> &nbsp; <a class="qindex" href="annotated.html">Class/Enum List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; </CENTER>
<HR>
-<!-- Generated by Doxygen 1.4.4 -->
-<h1>The <a class="el" href="classRtMidi.html">RtMidi</a> Tutorial </h1>
+<!-- Generated by Doxygen 1.5.8 -->
+<div class="contents">
+<h1>The RtMidi Tutorial</h1>
<p>
-<h3 align="center">1.0.7 </h3><center><a class="el" href="index.html#intro">Introduction</a> &nbsp;&nbsp; <a class="el" href="index.html#download">Download</a> &nbsp;&nbsp; <a class="el" href="index.html#start">Getting Started</a> &nbsp;&nbsp; <a class="el" href="index.html#error">Error Handling</a> &nbsp;&nbsp; <a class="el" href="index.html#probing">Probing Ports</a> &nbsp;&nbsp; <a class="el" href="index.html#output">MIDI Output</a> &nbsp;&nbsp; <a class="el" href="index.html#input">MIDI Input</a> &nbsp;&nbsp; <a class="el" href="index.html#virtual">Virtual Ports</a> &nbsp;&nbsp; <a class="el" href="index.html#compiling">Compiling</a> &nbsp;&nbsp; <a class="el" href="index.html#debug">Debugging</a> &nbsp;&nbsp; <a class="el" href="index.html#apinotes">API Notes</a> &nbsp;&nbsp; <a class="el" href="index.html#acknowledge">Acknowledgements</a> &nbsp;&nbsp; <a class="el" href="index.html#license">License</a></center><h2><a class="anchor" name="intro">
+<h3 align="center">1.0.8 </h3><center><a class="el" href="index.html#intro">Introduction</a> &nbsp;&nbsp; <a class="el" href="index.html#download">Download</a> &nbsp;&nbsp; <a class="el" href="index.html#start">Getting Started</a> &nbsp;&nbsp; <a class="el" href="index.html#error">Error Handling</a> &nbsp;&nbsp; <a class="el" href="index.html#probing">Probing Ports</a> &nbsp;&nbsp; <a class="el" href="index.html#output">MIDI Output</a> &nbsp;&nbsp; <a class="el" href="index.html#input">MIDI Input</a> &nbsp;&nbsp; <a class="el" href="index.html#virtual">Virtual Ports</a> &nbsp;&nbsp; <a class="el" href="index.html#compiling">Compiling</a> &nbsp;&nbsp; <a class="el" href="index.html#debug">Debugging</a> &nbsp;&nbsp; <a class="el" href="index.html#apinotes">API Notes</a> &nbsp;&nbsp; <a class="el" href="index.html#acknowledge">Acknowledgements</a> &nbsp;&nbsp; <a class="el" href="index.html#license">License</a></center><h2><a class="anchor" name="intro">
Introduction</a></h2>
-<a class="el" href="classRtMidi.html">RtMidi</a> is a set of C++ classes (<a class="el" href="classRtMidiIn.html">RtMidiIn</a> and <a class="el" href="classRtMidiOut.html">RtMidiOut</a>) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA), Macintosh OS X, SGI, and Windows (Multimedia Library) operating systems. <a class="el" href="classRtMidi.html">RtMidi</a> significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals:<p>
+<a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> is a set of C++ classes (<a class="el" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> and <a class="el" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a>) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA), Macintosh OS X, SGI, and Windows (Multimedia Library) operating systems. <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals:<p>
<ul>
<li>
object oriented C++ design </li>
@@ -24,64 +25,65 @@ only two header files and one source file for easy inclusion in programming proj
MIDI device enumeration </li>
</ul>
<p>
-MIDI input and output functionality are separated into two classes, <a class="el" href="classRtMidiIn.html">RtMidiIn</a> and <a class="el" href="classRtMidiOut.html">RtMidiOut</a>. Each class instance supports only a single MIDI connection. <a class="el" href="classRtMidi.html">RtMidi</a> does not provide timing functionality (i.e., output messages are sent immediately). Input messages are timestamped with delta times in seconds (via a <code>double</code> floating point type). MIDI data is passed to the user as raw bytes using an std::vector&lt;unsigned char&gt;.<h2><a class="anchor" name="download">
+MIDI input and output functionality are separated into two classes, <a class="el" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> and <a class="el" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a>. Each class instance supports only a single MIDI connection. <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> does not provide timing functionality (i.e., output messages are sent immediately). Input messages are timestamped with delta times in seconds (via a <code>double</code> floating point type). MIDI data is passed to the user as raw bytes using an std::vector&lt;unsigned char&gt;.<h2><a class="anchor" name="download">
Download</a></h2>
-Latest Release (7 December 2007): <a href="http://music.mcgill.ca/~gary/rtmidi/release/rtmidi-1.0.7.tar.gz">Version 1.0.7</a><h2><a class="anchor" name="start">
+Latest Release (29 January 2009): <a href="http://www.music.mcgill.ca/~gary/rtmidi/release/rtmidi-1.0.8.tar.gz">Version 1.0.8</a><h2><a class="anchor" name="start">
Getting Started</a></h2>
-The first thing that must be done when using <a class="el" href="classRtMidi.html">RtMidi</a> is to create an instance of the <a class="el" href="classRtMidiIn.html">RtMidiIn</a> or <a class="el" href="classRtMidiOut.html">RtMidiOut</a> subclasses. <a class="el" href="classRtMidi.html">RtMidi</a> is an abstract base class, which itself cannot be instantiated. Each default constructor attempts to establish any necessary "connections" with the underlying MIDI system. <a class="el" href="classRtMidi.html">RtMidi</a> uses C++ exceptions to report errors, necessitating try/catch blocks around many member functions. An <a class="el" href="classRtError.html">RtError</a> can be thrown during instantiation in some circumstances. A warning message may also be reported if no MIDI devices are found during instantiation. The <a class="el" href="classRtMidi.html">RtMidi</a> classes have been designed to work with "hot pluggable" or virtual (software) MIDI devices, making it possible to connect to MIDI devices that may not have been present when the classes were instantiated. The following code example demonstrates default object construction and destruction:<p>
+The first thing that must be done when using <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> is to create an instance of the <a class="el" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> or <a class="el" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a> subclasses. <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> is an abstract base class, which itself cannot be instantiated. Each default constructor attempts to establish any necessary "connections" with the underlying MIDI system. <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> uses C++ exceptions to report errors, necessitating try/catch blocks around many member functions. An <a class="el" href="classRtError.html" title="Exception handling class for RtAudio &amp; RtMidi.">RtError</a> can be thrown during instantiation in some circumstances. A warning message may also be reported if no MIDI devices are found during instantiation. The <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> classes have been designed to work with "hot pluggable" or virtual (software) MIDI devices, making it possible to connect to MIDI devices that may not have been present when the classes were instantiated. The following code example demonstrates default object construction and destruction:<p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include "RtMidi.h"</span>
<span class="keywordtype">int</span> main()
{
- <a class="code" href="classRtMidiIn.html">RtMidiIn</a> *midiin = 0;
+ <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> *midiin = 0;
<span class="comment">// RtMidiIn constructor</span>
<span class="keywordflow">try</span> {
- midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html">RtMidiIn</a>();
+ midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a>();
}
- <span class="keywordflow">catch</span> (<a class="code" href="classRtError.html">RtError</a> &amp;error) {
+ <span class="keywordflow">catch</span> (<a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error) {
<span class="comment">// Handle the exception here</span>
- error.<a class="code" href="classRtError.html#a2">printMessage</a>();
+ error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
}
<span class="comment">// Clean up</span>
<span class="keyword">delete</span> midiin;
}
</pre></div><p>
-Obviously, this example doesn't demonstrate any of the real functionality of <a class="el" href="classRtMidi.html">RtMidi</a>. However, all uses of <a class="el" href="classRtMidi.html">RtMidi</a> must begin with construction and must end with class destruction. Further, it is necessary that all class methods that can throw a C++ exception be called within a try/catch block.<h2><a class="anchor" name="error">
+Obviously, this example doesn't demonstrate any of the real functionality of <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a>. However, all uses of <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> must begin with construction and must end with class destruction. Further, it is necessary that all class methods that can throw a C++ exception be called within a try/catch block.<h2><a class="anchor" name="error">
Error Handling</a></h2>
-<a class="el" href="classRtMidi.html">RtMidi</a> uses a C++ exception handler called <a class="el" href="classRtError.html">RtError</a>, which is declared and defined in <a class="el" href="RtError_8h-source.html">RtError.h</a>. The <a class="el" href="classRtError.html">RtError</a> class is quite simple but it does allow errors to be "caught" by <a class="el" href="classRtError.html#w11">RtError::Type</a>. Many <a class="el" href="classRtMidi.html">RtMidi</a> methods can "throw" an <a class="el" href="classRtError.html">RtError</a>, most typically if a driver error occurs or an invalid function argument is specified. There are a number of cases within <a class="el" href="classRtMidi.html">RtMidi</a> where warning messages may be displayed but an exception is not thrown. There is a protected <a class="el" href="classRtMidi.html">RtMidi</a> method, error(), which can be modified to globally control how these messages are handled and reported. By default, error messages are not automatically displayed in <a class="el" href="classRtMidi.html">RtMidi</a> unless the preprocessor definition __RTMIDI_DEBUG__ is defined. Messages associated with caught exceptions can be displayed with, for example, the <a class="el" href="classRtError.html#a2">RtError::printMessage()</a> function.<h2><a class="anchor" name="probing">
+<a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> uses a C++ exception handler called <a class="el" href="classRtError.html" title="Exception handling class for RtAudio &amp; RtMidi.">RtError</a>, which is declared and defined in <a class="el" href="RtError_8h-source.html">RtError.h</a>. The <a class="el" href="classRtError.html" title="Exception handling class for RtAudio &amp; RtMidi.">RtError</a> class is quite simple but it does allow errors to be "caught" by <a class="el" href="classRtError.html#b04667aae01bffc354a9ac6bda6903ac" title="Defined RtError types.">RtError::Type</a>. Many <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> methods can "throw" an <a class="el" href="classRtError.html" title="Exception handling class for RtAudio &amp; RtMidi.">RtError</a>, most typically if a driver error occurs or an invalid function argument is specified. There are a number of cases within <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> where warning messages may be displayed but an exception is not thrown. There is a protected <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> method, error(), that can be modified to globally control how these messages are handled and reported. By default, error messages are not automatically displayed in <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> unless the preprocessor definition __RTMIDI_DEBUG__ is defined. Messages associated with caught exceptions can be displayed with, for example, the <a class="el" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">RtError::printMessage()</a> function.<h2><a class="anchor" name="probing">
Probing Ports</a></h2>
A programmer may wish to query the available MIDI ports before deciding which to use. The following example outlines how this can be done.<p>
<div class="fragment"><pre class="fragment"><span class="comment">// midiprobe.cpp</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>
+<span class="preprocessor">#include &lt;cstdlib&gt;</span>
<span class="preprocessor">#include "RtMidi.h"</span>
<span class="keywordtype">int</span> main()
{
- <a class="code" href="classRtMidiIn.html">RtMidiIn</a> *midiin = 0;
- <a class="code" href="classRtMidiOut.html">RtMidiOut</a> *midiout = 0;
+ <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> *midiin = 0;
+ <a class="code" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a> *midiout = 0;
<span class="comment">// RtMidiIn constructor</span>
<span class="keywordflow">try</span> {
- midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html">RtMidiIn</a>();
+ midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a>();
}
- <span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html">RtError</a> &amp;error ) {
- error.<a class="code" href="classRtError.html#a2">printMessage</a>();
+ <span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error ) {
+ error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
exit( EXIT_FAILURE );
}
<span class="comment">// Check inputs.</span>
- <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#a7">getPortCount</a>();
+ <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#62b1b38aa8e5f11cd66f03d59228f4e4" title="Return the number of available MIDI input ports.">getPortCount</a>();
std::cout &lt;&lt; <span class="stringliteral">"\nThere are "</span> &lt;&lt; nPorts &lt;&lt; <span class="stringliteral">" MIDI input sources available.\n"</span>;
std::string portName;
<span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nPorts; i++ ) {
<span class="keywordflow">try</span> {
- portName = midiin-&gt;<a class="code" href="classRtMidiIn.html#a8">getPortName</a>(i);
+ portName = midiin-&gt;<a class="code" href="classRtMidiIn.html#f2961fff09fa01a3d5bc0f0c5a042aaf" title="Return a string identifier for the specified MIDI input port number.">getPortName</a>(i);
}
- <span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html">RtError</a> &amp;error ) {
- error.<a class="code" href="classRtError.html#a2">printMessage</a>();
+ <span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error ) {
+ error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
<span class="keywordflow">goto</span> cleanup;
}
std::cout &lt;&lt; <span class="stringliteral">" Input Port #"</span> &lt;&lt; i+1 &lt;&lt; <span class="stringliteral">": "</span> &lt;&lt; portName &lt;&lt; <span class="charliteral">'\n'</span>;
@@ -89,22 +91,22 @@ A programmer may wish to query the available MIDI ports before deciding which to
<span class="comment">// RtMidiOut constructor</span>
<span class="keywordflow">try</span> {
- midiout = <span class="keyword">new</span> <a class="code" href="classRtMidiOut.html">RtMidiOut</a>();
+ midiout = <span class="keyword">new</span> <a class="code" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a>();
}
- <span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html">RtError</a> &amp;error ) {
- error.<a class="code" href="classRtError.html#a2">printMessage</a>();
+ <span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error ) {
+ error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
exit( EXIT_FAILURE );
}
<span class="comment">// Check outputs.</span>
- nPorts = midiout-&gt;<a class="code" href="classRtMidiOut.html#a5">getPortCount</a>();
+ nPorts = midiout-&gt;<a class="code" href="classRtMidiOut.html#d6cddbcc7faa20a7be229f765ade0877" title="Return the number of available MIDI output ports.">getPortCount</a>();
std::cout &lt;&lt; <span class="stringliteral">"\nThere are "</span> &lt;&lt; nPorts &lt;&lt; <span class="stringliteral">" MIDI output ports available.\n"</span>;
<span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nPorts; i++ ) {
<span class="keywordflow">try</span> {
- portName = midiout-&gt;<a class="code" href="classRtMidiOut.html#a6">getPortName</a>(i);
+ portName = midiout-&gt;<a class="code" href="classRtMidiOut.html#cc4ae0ab71a49ae7629075d5a9cd837c" title="Return a string identifier for the specified MIDI port type and number.">getPortName</a>(i);
}
- <span class="keywordflow">catch</span> (<a class="code" href="classRtError.html">RtError</a> &amp;error) {
- error.<a class="code" href="classRtError.html#a2">printMessage</a>();
+ <span class="keywordflow">catch</span> (<a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error) {
+ error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
<span class="keywordflow">goto</span> cleanup;
}
std::cout &lt;&lt; <span class="stringliteral">" Output Port #"</span> &lt;&lt; i+1 &lt;&lt; <span class="stringliteral">": "</span> &lt;&lt; portName &lt;&lt; <span class="charliteral">'\n'</span>;
@@ -120,46 +122,47 @@ A programmer may wish to query the available MIDI ports before deciding which to
}
</pre></div><h2><a class="anchor" name="output">
MIDI Output</a></h2>
-The <a class="el" href="classRtMidiOut.html">RtMidiOut</a> class provides simple functionality to immediately send messages over a MIDI connection. No timing functionality is provided.<p>
+The <a class="el" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a> class provides simple functionality to immediately send messages over a MIDI connection. No timing functionality is provided.<p>
In the following example, we omit necessary error checking and details regarding OS-dependent sleep functions. For a complete example, see the <code>midiout.cpp</code> program in the <code>tests</code> directory.<p>
<div class="fragment"><pre class="fragment"><span class="comment">// midiout.cpp</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>
+<span class="preprocessor">#include &lt;cstdlib&gt;</span>
<span class="preprocessor">#include "RtMidi.h"</span>
<span class="keywordtype">int</span> main()
{
- <a class="code" href="classRtMidiOut.html">RtMidiOut</a> *midiout = <span class="keyword">new</span> <a class="code" href="classRtMidiOut.html">RtMidiOut</a>();
+ <a class="code" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a> *midiout = <span class="keyword">new</span> <a class="code" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a>();
std::vector&lt;unsigned char&gt; message;
<span class="comment">// Check available ports.</span>
- <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiout-&gt;<a class="code" href="classRtMidiOut.html#a5">getPortCount</a>();
+ <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiout-&gt;<a class="code" href="classRtMidiOut.html#d6cddbcc7faa20a7be229f765ade0877" title="Return the number of available MIDI output ports.">getPortCount</a>();
<span class="keywordflow">if</span> ( nPorts == 0 ) {
std::cout &lt;&lt; <span class="stringliteral">"No ports available!\n"</span>;
<span class="keywordflow">goto</span> cleanup;
}
<span class="comment">// Open first available port.</span>
- midiout-&gt;<a class="code" href="classRtMidiOut.html#a2">openPort</a>( 0 );
+ midiout-&gt;<a class="code" href="classRtMidiOut.html#1b280d67317cd473a8816aeb2fe6c186" title="Open a MIDI output connection.">openPort</a>( 0 );
<span class="comment">// Send out a series of MIDI messages.</span>
<span class="comment">// Program change: 192, 5</span>
message.push_back( 192 );
message.push_back( 5 );
- midiout-&gt;<a class="code" href="classRtMidiOut.html#a7">sendMessage</a>( &amp;message );
+ midiout-&gt;<a class="code" href="classRtMidiOut.html#0bd8972ef8ac4e8d37ccc4b5d51c2eb3" title="Immediately send a single message out an open MIDI output port.">sendMessage</a>( &amp;message );
<span class="comment">// Control Change: 176, 7, 100 (volume)</span>
message[0] = 176;
message[1] = 7;
message.push_back( 100 );
- midiout-&gt;<a class="code" href="classRtMidiOut.html#a7">sendMessage</a>( &amp;message );
+ midiout-&gt;<a class="code" href="classRtMidiOut.html#0bd8972ef8ac4e8d37ccc4b5d51c2eb3" title="Immediately send a single message out an open MIDI output port.">sendMessage</a>( &amp;message );
<span class="comment">// Note On: 144, 64, 90</span>
message[0] = 144;
message[1] = 64;
message[2] = 90;
- midiout-&gt;<a class="code" href="classRtMidiOut.html#a7">sendMessage</a>( &amp;message );
+ midiout-&gt;<a class="code" href="classRtMidiOut.html#0bd8972ef8ac4e8d37ccc4b5d51c2eb3" title="Immediately send a single message out an open MIDI output port.">sendMessage</a>( &amp;message );
SLEEP( 500 ); <span class="comment">// Platform-dependent ... see example in tests directory.</span>
@@ -167,7 +170,7 @@ In the following example, we omit necessary error checking and details regarding
message[0] = 128;
message[1] = 64;
message[2] = 40;
- midiout-&gt;<a class="code" href="classRtMidiOut.html#a7">sendMessage</a>( &amp;message );
+ midiout-&gt;<a class="code" href="classRtMidiOut.html#0bd8972ef8ac4e8d37ccc4b5d51c2eb3" title="Immediately send a single message out an open MIDI output port.">sendMessage</a>( &amp;message );
<span class="comment">// Clean up</span>
cleanup:
@@ -177,14 +180,15 @@ In the following example, we omit necessary error checking and details regarding
}
</pre></div><h2><a class="anchor" name="input">
MIDI Input</a></h2>
-The <a class="el" href="classRtMidiIn.html">RtMidiIn</a> class uses an internal callback function or thread to receive incoming MIDI messages from a port or device. These messages are then either queued and read by the user via calls to the <a class="el" href="classRtMidiIn.html#a11">RtMidiIn::getMessage()</a> function or immediately passed to a user-specified callback function (which must be "registered" using the <a class="el" href="classRtMidiIn.html#a4">RtMidiIn::setCallback()</a> function). We'll provide examples of both usages.<p>
-The <a class="el" href="classRtMidiIn.html">RtMidiIn</a> class provides the <a class="el" href="classRtMidiIn.html#a10">RtMidiIn::ignoreTypes()</a> function to specify that certain MIDI message types be ignored. By default, sysem exclusive, timing, and active sensing messages are ignored.<h3><a class="anchor" name="qmidiin">
+The <a class="el" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> class uses an internal callback function or thread to receive incoming MIDI messages from a port or device. These messages are then either queued and read by the user via calls to the <a class="el" href="classRtMidiIn.html#1ba10ecd276b30a8579c7d60a9c890eb" title="Fill the user-provided vector with the data bytes for the next available MIDI message...">RtMidiIn::getMessage()</a> function or immediately passed to a user-specified callback function (which must be "registered" using the <a class="el" href="classRtMidiIn.html#7590563461c7467608a4b3806406b32d" title="Set a callback function to be invoked for incoming MIDI messages.">RtMidiIn::setCallback()</a> function). We'll provide examples of both usages.<p>
+The <a class="el" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> class provides the <a class="el" href="classRtMidiIn.html#f9507125aaa42276ccc01df576fc3533" title="Specify whether certain MIDI message types should be queued or ignored during input...">RtMidiIn::ignoreTypes()</a> function to specify that certain MIDI message types be ignored. By default, sysem exclusive, timing, and active sensing messages are ignored.<h3><a class="anchor" name="qmidiin">
Queued MIDI Input</a></h3>
-The <a class="el" href="classRtMidiIn.html#a11">RtMidiIn::getMessage()</a> function does not block. If a MIDI message is available in the queue, it is copied to the user-provided <code>std::vector&lt;unsigned char&gt;</code> container. When no MIDI message is available, the function returns an empty container. The default maximum MIDI queue size is 1024 messages. This value may be modified with the <a class="el" href="classRtMidiIn.html#a9">RtMidiIn::setQueueSizeLimit()</a> function. If the maximum queue size limit is reached, subsequent incoming MIDI messages are discarded until the queue size is reduced.<p>
+The <a class="el" href="classRtMidiIn.html#1ba10ecd276b30a8579c7d60a9c890eb" title="Fill the user-provided vector with the data bytes for the next available MIDI message...">RtMidiIn::getMessage()</a> function does not block. If a MIDI message is available in the queue, it is copied to the user-provided <code>std::vector&lt;unsigned char&gt;</code> container. When no MIDI message is available, the function returns an empty container. The default maximum MIDI queue size is 1024 messages. This value may be modified with the <a class="el" href="classRtMidiIn.html#2e15868916737039e0a34d47bffdf188" title="Set the maximum number of MIDI messages to be saved in the queue.">RtMidiIn::setQueueSizeLimit()</a> function. If the maximum queue size limit is reached, subsequent incoming MIDI messages are discarded until the queue size is reduced.<p>
In the following example, we omit some necessary error checking and details regarding OS-dependent sleep functions. For a more complete example, see the <code>qmidiin.cpp</code> program in the <code>tests</code> directory.<p>
<div class="fragment"><pre class="fragment"><span class="comment">// qmidiin.cpp</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>
+<span class="preprocessor">#include &lt;cstdlib&gt;</span>
<span class="preprocessor">#include &lt;signal.h&gt;</span>
<span class="preprocessor">#include "RtMidi.h"</span>
@@ -193,21 +197,21 @@ In the following example, we omit some necessary error checking and details rega
<span class="keywordtype">int</span> main()
{
- <a class="code" href="classRtMidiIn.html">RtMidiIn</a> *midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html">RtMidiIn</a>();
+ <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> *midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a>();
std::vector&lt;unsigned char&gt; message;
<span class="keywordtype">int</span> nBytes, i;
<span class="keywordtype">double</span> stamp;
<span class="comment">// Check available ports.</span>
- <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#a7">getPortCount</a>();
+ <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#62b1b38aa8e5f11cd66f03d59228f4e4" title="Return the number of available MIDI input ports.">getPortCount</a>();
<span class="keywordflow">if</span> ( nPorts == 0 ) {
std::cout &lt;&lt; <span class="stringliteral">"No ports available!\n"</span>;
<span class="keywordflow">goto</span> cleanup;
}
- midiin-&gt;<a class="code" href="classRtMidiIn.html#a2">openPort</a>( 0 );
+ midiin-&gt;<a class="code" href="classRtMidiIn.html#7e853661b1056083e07318d67c51f6fd" title="Open a MIDI input connection.">openPort</a>( 0 );
<span class="comment">// Don't ignore sysex, timing, or active sensing messages.</span>
- midiin-&gt;<a class="code" href="classRtMidiIn.html#a10">ignoreTypes</a>( <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span> );
+ midiin-&gt;<a class="code" href="classRtMidiIn.html#f9507125aaa42276ccc01df576fc3533" title="Specify whether certain MIDI message types should be queued or ignored during input...">ignoreTypes</a>( <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span> );
<span class="comment">// Install an interrupt handler function.</span>
done = <span class="keyword">false</span>;
@@ -216,12 +220,12 @@ In the following example, we omit some necessary error checking and details rega
<span class="comment">// Periodically check input queue.</span>
std::cout &lt;&lt; <span class="stringliteral">"Reading MIDI from port ... quit with Ctrl-C.\n"</span>;
<span class="keywordflow">while</span> ( !done ) {
- stamp = midiin-&gt;<a class="code" href="classRtMidiIn.html#a11">getMessage</a>( &amp;message );
+ stamp = midiin-&gt;<a class="code" href="classRtMidiIn.html#1ba10ecd276b30a8579c7d60a9c890eb" title="Fill the user-provided vector with the data bytes for the next available MIDI message...">getMessage</a>( &amp;message );
nBytes = message.size();
<span class="keywordflow">for</span> ( i=0; i&lt;nBytes; i++ )
- std::cout &lt;&lt; <span class="stringliteral">"Byte "</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">" = "</span> &lt;&lt; (int)message[i] &lt;&lt; <span class="stringliteral">", "</span>;
+ std::cout &lt;&lt; <span class="stringliteral">"Byte "</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">" = "</span> &lt;&lt; (<span class="keywordtype">int</span>)message[i] &lt;&lt; <span class="stringliteral">", "</span>;
<span class="keywordflow">if</span> ( nBytes &gt; 0 )
- std::cout &lt;&lt; <span class="stringliteral">"stamp = "</span> &lt;&lt; stamp &lt;&lt; <span class="charliteral">'\n'</span>;
+ std::cout &lt;&lt; <span class="stringliteral">"stamp = "</span> &lt;&lt; stamp &lt;&lt; std::endl;
<span class="comment">// Sleep for 10 milliseconds ... platform-dependent.</span>
SLEEP( 10 );
@@ -235,42 +239,43 @@ In the following example, we omit some necessary error checking and details rega
}
</pre></div><h3><a class="anchor" name="cmidiin">
MIDI Input with User Callback</a></h3>
-When set, a user-provided callback function will be invoked after the input of a complete MIDI message. It is possible to provide a pointer to user data which can be accessed in the callback function (not shown here). It is necessary to set the callback function immediately after opening the port to avoid having incoming messages written to the queue (which is not emptied when a callback function is set). If you are worried about this happening, you can check the queue using the RtMidi::getMessage() function to verify it is empty (after the callback function is set).<p>
+When set, a user-provided callback function will be invoked after the input of a complete MIDI message. It is possible to provide a pointer to user data that can be accessed in the callback function (not shown here). It is necessary to set the callback function immediately after opening the port to avoid having incoming messages written to the queue (which is not emptied when a callback function is set). If you are worried about this happening, you can check the queue using the RtMidi::getMessage() function to verify it is empty (after the callback function is set).<p>
In the following example, we omit some necessary error checking. For a more complete example, see the <code>cmidiin.cpp</code> program in the <code>tests</code> directory.<p>
<div class="fragment"><pre class="fragment"><span class="comment">// cmidiin.cpp</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>
+<span class="preprocessor">#include &lt;cstdlib&gt;</span>
<span class="preprocessor">#include "RtMidi.h"</span>
<span class="keywordtype">void</span> mycallback( <span class="keywordtype">double</span> deltatime, std::vector&lt; unsigned char &gt; *message, <span class="keywordtype">void</span> *userData )
{
<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nBytes = message-&gt;size();
<span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nBytes; i++ )
- std::cout &lt;&lt; <span class="stringliteral">"Byte "</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">" = "</span> &lt;&lt; (int)message-&gt;at(i) &lt;&lt; <span class="stringliteral">", "</span>;
+ std::cout &lt;&lt; <span class="stringliteral">"Byte "</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">" = "</span> &lt;&lt; (<span class="keywordtype">int</span>)message-&gt;at(i) &lt;&lt; <span class="stringliteral">", "</span>;
<span class="keywordflow">if</span> ( nBytes &gt; 0 )
- std::cout &lt;&lt; <span class="stringliteral">"stamp = "</span> &lt;&lt; deltatime &lt;&lt; <span class="charliteral">'\n'</span>;
+ std::cout &lt;&lt; <span class="stringliteral">"stamp = "</span> &lt;&lt; deltatime &lt;&lt; std::endl;
}
<span class="keywordtype">int</span> main()
{
- <a class="code" href="classRtMidiIn.html">RtMidiIn</a> *midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html">RtMidiIn</a>();
+ <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> *midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a>();
<span class="comment">// Check available ports.</span>
- <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#a7">getPortCount</a>();
+ <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#62b1b38aa8e5f11cd66f03d59228f4e4" title="Return the number of available MIDI input ports.">getPortCount</a>();
<span class="keywordflow">if</span> ( nPorts == 0 ) {
std::cout &lt;&lt; <span class="stringliteral">"No ports available!\n"</span>;
<span class="keywordflow">goto</span> cleanup;
}
- midiin-&gt;<a class="code" href="classRtMidiIn.html#a2">openPort</a>( 0 );
+ midiin-&gt;<a class="code" href="classRtMidiIn.html#7e853661b1056083e07318d67c51f6fd" title="Open a MIDI input connection.">openPort</a>( 0 );
<span class="comment">// Set our callback function. This should be done immediately after</span>
<span class="comment">// opening the port to avoid having incoming messages written to the</span>
<span class="comment">// queue.</span>
- midiin-&gt;<a class="code" href="classRtMidiIn.html#a4">setCallback</a>( &amp;mycallback );
+ midiin-&gt;<a class="code" href="classRtMidiIn.html#7590563461c7467608a4b3806406b32d" title="Set a callback function to be invoked for incoming MIDI messages.">setCallback</a>( &amp;mycallback );
<span class="comment">// Don't ignore sysex, timing, or active sensing messages.</span>
- midiin-&gt;<a class="code" href="classRtMidiIn.html#a10">ignoreTypes</a>( <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span> );
+ midiin-&gt;<a class="code" href="classRtMidiIn.html#f9507125aaa42276ccc01df576fc3533" title="Specify whether certain MIDI message types should be queued or ignored during input...">ignoreTypes</a>( <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span> );
std::cout &lt;&lt; <span class="stringliteral">"\nReading MIDI input ... press &lt;enter&gt; to quit.\n"</span>;
<span class="keywordtype">char</span> input;
@@ -284,9 +289,9 @@ In the following example, we omit some necessary error checking. For a more comp
}
</pre></div><h2><a class="anchor" name="virtual">
Virtual Ports</a></h2>
-The Linux ALSA and Macintosh CoreMIDI APIs allow for the establishment of virtual input and output MIDI ports to which other software clients can connect. <a class="el" href="classRtMidi.html">RtMidi</a> incorporates this functionality with the <a class="el" href="classRtMidiIn.html#a3">RtMidiIn::openVirtualPort()</a> and <a class="el" href="classRtMidiOut.html#a4">RtMidiOut::openVirtualPort()</a> functions. Any messages sent with the <a class="el" href="classRtMidiOut.html#a7">RtMidiOut::sendMessage()</a> function will also be transmitted through an open virtual output port. If a virtual input port is open and a user callback function is set, the callback function will be invoked when messages arrive via that port. If a callback function is not set, the user must poll the input queue to check whether messages have arrived. No notification is provided for the establishment of a client connection via a virtual port.<h2><a class="anchor" name="compiling">
+The Linux ALSA and Macintosh CoreMIDI APIs allow for the establishment of virtual input and output MIDI ports to which other software clients can connect. <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> incorporates this functionality with the <a class="el" href="classRtMidiIn.html#245261b3f12ce727faed18fcfeef18c2" title="Create a virtual input port, with optional name, to allow software connections (OS...">RtMidiIn::openVirtualPort()</a> and <a class="el" href="classRtMidiOut.html#47068e1c076d91fd89587c0ccdeddc7a" title="Create a virtual output port, with optional name, to allow software connections (OS...">RtMidiOut::openVirtualPort()</a> functions. Any messages sent with the <a class="el" href="classRtMidiOut.html#0bd8972ef8ac4e8d37ccc4b5d51c2eb3" title="Immediately send a single message out an open MIDI output port.">RtMidiOut::sendMessage()</a> function will also be transmitted through an open virtual output port. If a virtual input port is open and a user callback function is set, the callback function will be invoked when messages arrive via that port. If a callback function is not set, the user must poll the input queue to check whether messages have arrived. No notification is provided for the establishment of a client connection via a virtual port.<h2><a class="anchor" name="compiling">
Compiling</a></h2>
-In order to compile <a class="el" href="classRtMidi.html">RtMidi</a> for a specific OS and API, it is necessary to supply the appropriate preprocessor definition and library within the compiler statement: <p>
+In order to compile <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> for a specific OS and API, it is necessary to supply the appropriate preprocessor definition and library within the compiler statement: <p>
<table border="2" cols="5" width="100%" cellspacing="3" cellpadding="3">
<tr bgcolor="beige">
<td width="5%"><b>OS:</b> </td><td width="5%"><b>MIDI API:</b> </td><td width="5%"><b>Preprocessor Definition:</b> </td><td width="5%"><b>Library or Framework:</b> </td><td><b>Example Compiler Statement:</b> </td></tr>
@@ -302,38 +307,47 @@ In order to compile <a class="el" href="classRtMidi.html">RtMidi</a> for a speci
<p>
The example compiler statements above could be used to compile the <code>midiprobe.cpp</code> example file, assuming that <code>midiprobe.cpp</code>, <code><a class="el" href="RtMidi_8h-source.html">RtMidi.h</a></code>, <code><a class="el" href="RtError_8h-source.html">RtError.h</a></code>, and <code>RtMidi.cpp</code> all exist in the same directory.<h2><a class="anchor" name="debug">
Debugging</a></h2>
-If you are having problems getting <a class="el" href="classRtMidi.html">RtMidi</a> to run on your system, try passing the preprocessor definition <code>__RTMIDI_DEBUG__</code> to the compiler (or uncomment the definition at the bottom of <a class="el" href="RtMidi_8h-source.html">RtMidi.h</a>). A variety of warning messages will be displayed which may help in determining the problem. Also try using the programs included in the <code>test</code> directory. The program <code>midiprobe</code> displays the queried capabilities of all MIDI ports found.<h2><a class="anchor" name="apinotes">
+If you are having problems getting <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> to run on your system, try passing the preprocessor definition <code>__RTMIDI_DEBUG__</code> to the compiler (or uncomment the definition at the bottom of <a class="el" href="RtMidi_8h-source.html">RtMidi.h</a>). A variety of warning messages will be displayed that may help in determining the problem. Also try using the programs included in the <code>test</code> directory. The program <code>midiprobe</code> displays the queried capabilities of all MIDI ports found.<h2><a class="anchor" name="apinotes">
API Notes</a></h2>
-<a class="el" href="classRtMidi.html">RtMidi</a> is designed to provide a common API across the various supported operating systems and audio libraries. Despite that, some issues should be mentioned with regard to each.<h3><a class="anchor" name="linux">
+<a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> is designed to provide a common API across the various supported operating systems and audio libraries. Despite that, some issues should be mentioned with regard to each.<h3><a class="anchor" name="linux">
Linux:</a></h3>
-<a class="el" href="classRtMidi.html">RtMidi</a> for Linux was developed using the Fedora distribution. A decision was made to not include support for the OSS API because the OSS API provides such limited functionality and because <a href="http://www.alsa-project.org/">ALSA</a> support is now incorporated in the Linux kernel. <a class="el" href="classRtMidi.html">RtMidi</a> uses the ALSA sequencer API, which allows for virtual software input and output ports.<h3><a class="anchor" name="macosx">
+<a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> for Linux was developed using the Fedora distribution. A decision was made to not include support for the OSS API because the OSS API provides such limited functionality and because <a href="http://www.alsa-project.org/">ALSA</a> support is now incorporated in the Linux kernel. <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> uses the ALSA sequencer API, which allows for virtual software input and output ports.<h3><a class="anchor" name="macosx">
Macintosh OS X (CoreAudio):</a></h3>
The Apple CoreMidi API allows for the establishment of virtual input and output ports to which other software applications can connect.<h3><a class="anchor" name="irix">
Irix (SGI):</a></h3>
-The Irix version of <a class="el" href="classRtMidi.html">RtMidi</a> was written and tested on an SGI Indy running Irix version 6.5.4 and the MD audio library.<h3><a class="anchor" name="windowsds">
+The Irix version of <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> was written and tested on an SGI Indy running Irix version 6.5.4 and the MD audio library.<h3><a class="anchor" name="windowsds">
Windows (Multimedia Library):</a></h3>
-The Windows Multimedia library MIDI calls used in <a class="el" href="classRtMidi.html">RtMidi</a> do not make use of streaming functionality. <a class="el" href="classRtMidi.html">RtMidi</a> was originally developed with Visual C++ version 6.0.<p>
+The <code>configure</code> script provides support for the MinGW compiler.<p>
+The Windows Multimedia library MIDI calls used in <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> do not make use of streaming functionality. Incoming system exclusive messages read by <a class="el" href="classRtMidiIn.html" title="A realtime MIDI input class.">RtMidiIn</a> are limited to a length as defined by the preprocessor definition RT_SYSEX_BUFFER_SIZE (set in RtMidi.cpp). The default value is 1024. There is no such limit for outgoing sysex messages via <a class="el" href="classRtMidiOut.html" title="A realtime MIDI output class.">RtMidiOut</a>.<p>
+<a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a> was originally developed with Visual C++ version 6.0.<p>
The <code>configure</code> script provides support for the MinGW compiler.<h2><a class="anchor" name="acknowledge">
Acknowledgements</a></h2>
-Many thanks to the following people for providing bug fixes: <ul>
+Many thanks to the following people for providing bug fixes and improvements: <ul>
<li>
-Pedro Lopez-Cabanillas (ALSA sequencer API) </li>
+Pedro Lopez-Cabanillas (ALSA sequencer API, client naming) </li>
<li>
Eduardo Coutinho (Windows device names) </li>
<li>
Jean-Baptiste Berruchon (Windows sysex code) </li>
+<li>
+Christoph Eckert (ALSA sysex fixes) </li>
+<li>
+Immanuel Litzroth (OS-X sysex fix) </li>
+<li>
+Axel Schmidt (client naming) </li>
</ul>
<h2><a class="anchor" name="license">
License</a></h2>
-<a class="el" href="classRtMidi.html">RtMidi</a>: realtime MIDI i/o C++ classes<br>
- Copyright (c) 2003-2007 Gary P. Scavone<p>
+<a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output.">RtMidi</a>: realtime MIDI i/o C++ classes<br>
+ Copyright (c) 2003-2009 Gary P. Scavone<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:<p>
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.<p>
Any person wishing to distribute modifications to the Software is requested to send the modifications to the original developer so that they can be incorporated into the canonical version.<p>
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. <HR>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. </div>
+<HR>
<table><tr><td><img src="../images/mcgill.gif" width=165></td>
- <td>&copy;2003-2007 Gary P. Scavone, McGill University. All Rights Reserved.<br>
+ <td>&copy;2003-2009 Gary P. Scavone, McGill University. All Rights Reserved.<br>
Maintained by Gary P. Scavone, gary at music.mcgill.ca</td></tr>
</table>