This file is indexed.

/usr/share/doc/librtmidi-dev/api_ref/index.html is in librtmidi-doc 3.0.0~ds1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<HTML>
<HEAD>
<TITLE>The RtMidi Tutorial</TITLE>
<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<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.8.13 -->
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">The <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a> Tutorial </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><center><a class="el" href="index.html#intro">Introduction</a> &#160;&#160; <a class="el" href="index.html#download">Download</a> &#160;&#160; <a class="el" href="index.html#start">Getting Started</a> &#160;&#160; <a class="el" href="index.html#error">Error Handling</a> &#160;&#160; <a class="el" href="index.html#probing">Probing Ports</a> &#160;&#160; <a class="el" href="index.html#output">MIDI Output</a> &#160;&#160; <a class="el" href="index.html#input">MIDI Input</a> &#160;&#160; <a class="el" href="index.html#virtual">Virtual Ports</a> &#160;&#160; <a class="el" href="index.html#compiling">Compiling</a> &#160;&#160; <a class="el" href="index.html#debug">Debugging</a> &#160;&#160; <a class="el" href="index.html#multi">Using Simultaneous Multiple APIs</a> &#160;&#160; <a class="el" href="index.html#apinotes">API Notes</a> &#160;&#160; <a class="el" href="index.html#acknowledge">Development &amp; Acknowledgements</a> &#160;&#160; <a class="el" href="index.html#license">License</a></center><h1><a class="anchor" id="intro"></a>
Introduction</h1>
<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>, <a class="el" href="classRtMidiOut.html" title="A realtime MIDI output class. ">RtMidiOut</a> and API-specific classes) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA &amp; JACK), Macintosh OS X (CoreMIDI &amp; JACK), 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>
<li>simple, common API across all supported platforms</li>
<li>only one header and one source file for easy inclusion in programming projects</li>
<li>MIDI device enumeration</li>
</ul>
<p>Where applicable, multiple API support can be compiled and a particular API specified when creating an RtAudio instance.</p>
<p>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;.</p>
<h1><a class="anchor" id="whatsnew"></a>
What's New (Version 3.0.0)</h1>
<p>The version number has been bumped to 3.0.0 because of the past API change concerning the renaming of the RtError class to <a class="el" href="classRtMidiError.html" title="Exception handling class for RtMidi. ">RtMidiError</a>. Changes in this release include:</p>
<ul>
<li>see git history for complete list of changes</li>
<li>new sendMessage() function that does not use std::vector</li>
<li>various std::string updates, including use of UTF8 for port names</li>
<li>fixes for the MIDI queue</li>
<li>various build system updates and code efficiencies</li>
</ul>
<h1><a class="anchor" id="download"></a>
Download</h1>
<p>Latest Release (31 August 2017): <a href="http://www.music.mcgill.ca/~gary/rtmidi/release/rtmidi-3.0.0.tar.gz">Version 3.0.0</a></p>
<h1><a class="anchor" id="start"></a>
Getting Started</h1>
<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="classRtMidiError.html" title="Exception handling class for RtMidi. ">RtMidiError</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"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="RtMidi_8h.html">RtMidi.h</a>&quot;</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() {</div><div class="line">  <span class="keywordflow">try</span> {</div><div class="line">    <a class="code" href="classRtMidiIn.html">RtMidiIn</a> midiin;</div><div class="line">  } <span class="keywordflow">catch</span> (<a class="code" href="classRtMidiError.html">RtMidiError</a> &amp;error) {</div><div class="line">    <span class="comment">// Handle the exception here</span></div><div class="line">    error.<a class="code" href="classRtMidiError.html#a678201ec055ab2dc9e285cbe41d61c0a">printMessage</a>();</div><div class="line">  }</div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p>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.</p>
<h1><a class="anchor" id="error"></a>
Error Handling</h1>
<p><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="classRtMidiError.html" title="Exception handling class for RtMidi. ">RtMidiError</a>, which is declared and defined in <a class="el" href="RtMidi_8h.html">RtMidi.h</a>. The <a class="el" href="classRtMidiError.html" title="Exception handling class for RtMidi. ">RtMidiError</a> class is quite simple but it does allow errors to be "caught" by <a class="el" href="classRtMidiError.html#a741314057cec5fb8c743c12f284905ee" title="Defined RtMidiError types. ">RtMidiError::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="classRtMidiError.html" title="Exception handling class for RtMidi. ">RtMidiError</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. A client error callback function can be specified (via the <a class="el" href="classRtMidi.html#aa6d6f2e0d06c64268c8898aa15f3a5df" title="Set an error callback function to be invoked when an error has occured. ">RtMidi::setErrorCallback</a> function) that is invoked when an error occurs. 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 <b>RTMIDI_DEBUG</b> is defined during compilation. Messages associated with caught exceptions can be displayed with, for example, the <a class="el" href="classRtMidiError.html#a678201ec055ab2dc9e285cbe41d61c0a" title="Prints thrown error message to stderr. ">RtMidiError::printMessage()</a> function.</p>
<h1><a class="anchor" id="probing"></a>
Probing Ports</h1>
<p>A client generally must query the available MIDI ports before deciding which to use. The following example outlines how this can be done.</p>
<div class="fragment"><div class="line"><span class="comment">// midiprobe.cpp</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="RtMidi_8h.html">RtMidi.h</a>&quot;</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main()</div><div class="line">{</div><div class="line">  <a class="code" href="classRtMidiIn.html">RtMidiIn</a>  *midiin = 0;</div><div class="line">  <a class="code" href="classRtMidiOut.html">RtMidiOut</a> *midiout = 0;</div><div class="line"></div><div class="line">  <span class="comment">// RtMidiIn constructor</span></div><div class="line">  <span class="keywordflow">try</span> {</div><div class="line">    midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html">RtMidiIn</a>();</div><div class="line">  }</div><div class="line">  <span class="keywordflow">catch</span> ( <a class="code" href="classRtMidiError.html">RtMidiError</a> &amp;error ) {</div><div class="line">    error.<a class="code" href="classRtMidiError.html#a678201ec055ab2dc9e285cbe41d61c0a">printMessage</a>();</div><div class="line">    exit( EXIT_FAILURE );</div><div class="line">  }</div><div class="line"></div><div class="line">  <span class="comment">// Check inputs.</span></div><div class="line">  <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#a62b1b38aa8e5f11cd66f03d59228f4e4">getPortCount</a>();</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;\nThere are &quot;</span> &lt;&lt; nPorts &lt;&lt; <span class="stringliteral">&quot; MIDI input sources available.\n&quot;</span>;</div><div class="line">  std::string portName;</div><div class="line">  <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nPorts; i++ ) {</div><div class="line">    <span class="keywordflow">try</span> {</div><div class="line">      portName = midiin-&gt;<a class="code" href="classRtMidiIn.html#af2961fff09fa01a3d5bc0f0c5a042aaf">getPortName</a>(i);</div><div class="line">    }</div><div class="line">    <span class="keywordflow">catch</span> ( <a class="code" href="classRtMidiError.html">RtMidiError</a> &amp;error ) {</div><div class="line">      error.<a class="code" href="classRtMidiError.html#a678201ec055ab2dc9e285cbe41d61c0a">printMessage</a>();</div><div class="line">      <span class="keywordflow">goto</span> cleanup;</div><div class="line">    }</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;  Input Port #&quot;</span> &lt;&lt; i+1 &lt;&lt; <span class="stringliteral">&quot;: &quot;</span> &lt;&lt; portName &lt;&lt; <span class="charliteral">&#39;\n&#39;</span>;</div><div class="line">  }</div><div class="line"></div><div class="line">  <span class="comment">// RtMidiOut constructor</span></div><div class="line">  <span class="keywordflow">try</span> {</div><div class="line">    midiout = <span class="keyword">new</span> <a class="code" href="classRtMidiOut.html">RtMidiOut</a>();</div><div class="line">  }</div><div class="line">  <span class="keywordflow">catch</span> ( <a class="code" href="classRtMidiError.html">RtMidiError</a> &amp;error ) {</div><div class="line">    error.<a class="code" href="classRtMidiError.html#a678201ec055ab2dc9e285cbe41d61c0a">printMessage</a>();</div><div class="line">    exit( EXIT_FAILURE );</div><div class="line">  }</div><div class="line"></div><div class="line">  <span class="comment">// Check outputs.</span></div><div class="line">  nPorts = midiout-&gt;<a class="code" href="classRtMidiOut.html#a0c4d662e1c398ddf35a2dbaf66f50976">getPortCount</a>();</div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;\nThere are &quot;</span> &lt;&lt; nPorts &lt;&lt; <span class="stringliteral">&quot; MIDI output ports available.\n&quot;</span>;</div><div class="line">  <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nPorts; i++ ) {</div><div class="line">    <span class="keywordflow">try</span> {</div><div class="line">      portName = midiout-&gt;<a class="code" href="classRtMidiOut.html#acc4ae0ab71a49ae7629075d5a9cd837c">getPortName</a>(i);</div><div class="line">    }</div><div class="line">    <span class="keywordflow">catch</span> (<a class="code" href="classRtMidiError.html">RtMidiError</a> &amp;error) {</div><div class="line">      error.<a class="code" href="classRtMidiError.html#a678201ec055ab2dc9e285cbe41d61c0a">printMessage</a>();</div><div class="line">      <span class="keywordflow">goto</span> cleanup;</div><div class="line">    }</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;  Output Port #&quot;</span> &lt;&lt; i+1 &lt;&lt; <span class="stringliteral">&quot;: &quot;</span> &lt;&lt; portName &lt;&lt; <span class="charliteral">&#39;\n&#39;</span>;</div><div class="line">  }</div><div class="line">  std::cout &lt;&lt; <span class="charliteral">&#39;\n&#39;</span>;</div><div class="line"></div><div class="line">  <span class="comment">// Clean up</span></div><div class="line"> cleanup:</div><div class="line">  <span class="keyword">delete</span> midiin;</div><div class="line">  <span class="keyword">delete</span> midiout;</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h1><a class="anchor" id="output"></a>
MIDI Output</h1>
<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. Note that there is an overloaded <a class="el" href="classRtMidiOut.html#a19c7049a840a0181a0ddd4b14e99c651" title="Immediately send a single message out an open MIDI output port. ">RtMidiOut::sendMessage()</a> function that does not use std::vectors.</p>
<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"><div class="line"><span class="comment">// midiout.cpp</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="RtMidi_8h.html">RtMidi.h</a>&quot;</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main()</div><div class="line">{</div><div class="line">  <a class="code" href="classRtMidiOut.html">RtMidiOut</a> *midiout = <span class="keyword">new</span> <a class="code" href="classRtMidiOut.html">RtMidiOut</a>();</div><div class="line">  std::vector&lt;unsigned char&gt; message;</div><div class="line"></div><div class="line">  <span class="comment">// Check available ports.</span></div><div class="line">  <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiout-&gt;<a class="code" href="classRtMidiOut.html#a0c4d662e1c398ddf35a2dbaf66f50976">getPortCount</a>();</div><div class="line">  <span class="keywordflow">if</span> ( nPorts == 0 ) {</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;No ports available!\n&quot;</span>;</div><div class="line">    <span class="keywordflow">goto</span> cleanup;</div><div class="line">  }</div><div class="line"></div><div class="line">  <span class="comment">// Open first available port.</span></div><div class="line">  midiout-&gt;<a class="code" href="classRtMidiOut.html#a4c29a5e7c0f5c088953ef02f3c38d4f3">openPort</a>( 0 );</div><div class="line"></div><div class="line">  <span class="comment">// Send out a series of MIDI messages.</span></div><div class="line"></div><div class="line">  <span class="comment">// Program change: 192, 5</span></div><div class="line">  message.push_back( 192 );</div><div class="line">  message.push_back( 5 );</div><div class="line">  midiout-&gt;<a class="code" href="classRtMidiOut.html#a19c7049a840a0181a0ddd4b14e99c651">sendMessage</a>( &amp;message );</div><div class="line"></div><div class="line">  <span class="comment">// Control Change: 176, 7, 100 (volume)</span></div><div class="line">  message[0] = 176;</div><div class="line">  message[1] = 7;</div><div class="line">  message.push_back( 100 );</div><div class="line">  midiout-&gt;<a class="code" href="classRtMidiOut.html#a19c7049a840a0181a0ddd4b14e99c651">sendMessage</a>( &amp;message );</div><div class="line"></div><div class="line">  <span class="comment">// Note On: 144, 64, 90</span></div><div class="line">  message[0] = 144;</div><div class="line">  message[1] = 64;</div><div class="line">  message[2] = 90;</div><div class="line">  midiout-&gt;<a class="code" href="classRtMidiOut.html#a19c7049a840a0181a0ddd4b14e99c651">sendMessage</a>( &amp;message );</div><div class="line"></div><div class="line">  SLEEP( 500 ); <span class="comment">// Platform-dependent ... see example in tests directory.</span></div><div class="line"></div><div class="line">  <span class="comment">// Note Off: 128, 64, 40</span></div><div class="line">  message[0] = 128;</div><div class="line">  message[1] = 64;</div><div class="line">  message[2] = 40;</div><div class="line">  midiout-&gt;<a class="code" href="classRtMidiOut.html#a19c7049a840a0181a0ddd4b14e99c651">sendMessage</a>( &amp;message );</div><div class="line"></div><div class="line">  <span class="comment">// Clean up</span></div><div class="line"> cleanup:</div><div class="line">  <span class="keyword">delete</span> midiout;</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h1><a class="anchor" id="input"></a>
MIDI Input</h1>
<p>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#a1ba10ecd276b30a8579c7d60a9c890eb" title="Fill the user-provided vector with the data bytes for the next available MIDI message in the input qu...">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#a7590563461c7467608a4b3806406b32d" title="Set a callback function to be invoked for incoming MIDI messages. ">RtMidiIn::setCallback()</a> function). We'll provide examples of both usages.</p>
<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#af9507125aaa42276ccc01df576fc3533" 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, system exclusive, timing, and active sensing messages are ignored.</p>
<h2><a class="anchor" id="qmidiin"></a>
Queued MIDI Input</h2>
<p>The <a class="el" href="classRtMidiIn.html#a1ba10ecd276b30a8579c7d60a9c890eb" title="Fill the user-provided vector with the data bytes for the next available MIDI message in the input qu...">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 RtMidiIn::setQueueSizeLimit() function. If the maximum queue size limit is reached, subsequent incoming MIDI messages are discarded until the queue size is reduced.</p>
<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"><div class="line"><span class="comment">// qmidiin.cpp</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;signal.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="RtMidi_8h.html">RtMidi.h</a>&quot;</span></div><div class="line"></div><div class="line"><span class="keywordtype">bool</span> done;</div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> finish(<span class="keywordtype">int</span> ignore){ done = <span class="keyword">true</span>; }</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main()</div><div class="line">{</div><div class="line">  <a class="code" href="classRtMidiIn.html">RtMidiIn</a> *midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html">RtMidiIn</a>();</div><div class="line">  std::vector&lt;unsigned char&gt; message;</div><div class="line">  <span class="keywordtype">int</span> nBytes, i;</div><div class="line">  <span class="keywordtype">double</span> stamp;</div><div class="line"></div><div class="line">  <span class="comment">// Check available ports.</span></div><div class="line">  <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#a62b1b38aa8e5f11cd66f03d59228f4e4">getPortCount</a>();</div><div class="line">  <span class="keywordflow">if</span> ( nPorts == 0 ) {</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;No ports available!\n&quot;</span>;</div><div class="line">    <span class="keywordflow">goto</span> cleanup;</div><div class="line">  }</div><div class="line">  midiin-&gt;<a class="code" href="classRtMidiIn.html#a466c94692550aa109d9e7536bf5d9add">openPort</a>( 0 );</div><div class="line"></div><div class="line">  <span class="comment">// Don&#39;t ignore sysex, timing, or active sensing messages.</span></div><div class="line">  midiin-&gt;<a class="code" href="classRtMidiIn.html#af9507125aaa42276ccc01df576fc3533">ignoreTypes</a>( <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span> );</div><div class="line"></div><div class="line">  <span class="comment">// Install an interrupt handler function.</span></div><div class="line">  done = <span class="keyword">false</span>;</div><div class="line">  (void) signal(SIGINT, finish);</div><div class="line"></div><div class="line">  <span class="comment">// Periodically check input queue.</span></div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;Reading MIDI from port ... quit with Ctrl-C.\n&quot;</span>;</div><div class="line">  <span class="keywordflow">while</span> ( !done ) {</div><div class="line">    stamp = midiin-&gt;<a class="code" href="classRtMidiIn.html#a1ba10ecd276b30a8579c7d60a9c890eb">getMessage</a>( &amp;message );</div><div class="line">    nBytes = message.size();</div><div class="line">    <span class="keywordflow">for</span> ( i=0; i&lt;nBytes; i++ )</div><div class="line">      std::cout &lt;&lt; <span class="stringliteral">&quot;Byte &quot;</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">&quot; = &quot;</span> &lt;&lt; (<span class="keywordtype">int</span>)message[i] &lt;&lt; <span class="stringliteral">&quot;, &quot;</span>;</div><div class="line">    <span class="keywordflow">if</span> ( nBytes &gt; 0 )</div><div class="line">      std::cout &lt;&lt; <span class="stringliteral">&quot;stamp = &quot;</span> &lt;&lt; stamp &lt;&lt; std::endl;</div><div class="line"></div><div class="line">    <span class="comment">// Sleep for 10 milliseconds ... platform-dependent.</span></div><div class="line">    SLEEP( 10 );</div><div class="line">  }</div><div class="line"></div><div class="line">  <span class="comment">// Clean up</span></div><div class="line"> cleanup:</div><div class="line">  <span class="keyword">delete</span> midiin;</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="cmidiin"></a>
MIDI Input with User Callback</h2>
<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>
<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"><div class="line"><span class="comment">// cmidiin.cpp</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="RtMidi_8h.html">RtMidi.h</a>&quot;</span></div><div class="line"></div><div class="line"><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 )</div><div class="line">{</div><div class="line">  <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nBytes = message-&gt;size();</div><div class="line">  <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nBytes; i++ )</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;Byte &quot;</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">&quot; = &quot;</span> &lt;&lt; (<span class="keywordtype">int</span>)message-&gt;at(i) &lt;&lt; <span class="stringliteral">&quot;, &quot;</span>;</div><div class="line">  <span class="keywordflow">if</span> ( nBytes &gt; 0 )</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;stamp = &quot;</span> &lt;&lt; deltatime &lt;&lt; std::endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main()</div><div class="line">{</div><div class="line">  <a class="code" href="classRtMidiIn.html">RtMidiIn</a> *midiin = <span class="keyword">new</span> <a class="code" href="classRtMidiIn.html">RtMidiIn</a>();</div><div class="line"></div><div class="line">  <span class="comment">// Check available ports.</span></div><div class="line">  <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nPorts = midiin-&gt;<a class="code" href="classRtMidiIn.html#a62b1b38aa8e5f11cd66f03d59228f4e4">getPortCount</a>();</div><div class="line">  <span class="keywordflow">if</span> ( nPorts == 0 ) {</div><div class="line">    std::cout &lt;&lt; <span class="stringliteral">&quot;No ports available!\n&quot;</span>;</div><div class="line">    <span class="keywordflow">goto</span> cleanup;</div><div class="line">  }</div><div class="line"></div><div class="line">  midiin-&gt;<a class="code" href="classRtMidiIn.html#a466c94692550aa109d9e7536bf5d9add">openPort</a>( 0 );</div><div class="line"></div><div class="line">  <span class="comment">// Set our callback function.  This should be done immediately after</span></div><div class="line">  <span class="comment">// opening the port to avoid having incoming messages written to the</span></div><div class="line">  <span class="comment">// queue.</span></div><div class="line">  midiin-&gt;<a class="code" href="classRtMidiIn.html#a7590563461c7467608a4b3806406b32d">setCallback</a>( &amp;mycallback );</div><div class="line"></div><div class="line">  <span class="comment">// Don&#39;t ignore sysex, timing, or active sensing messages.</span></div><div class="line">  midiin-&gt;<a class="code" href="classRtMidiIn.html#af9507125aaa42276ccc01df576fc3533">ignoreTypes</a>( <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span> );</div><div class="line"></div><div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;\nReading MIDI input ... press &lt;enter&gt; to quit.\n&quot;</span>;</div><div class="line">  <span class="keywordtype">char</span> input;</div><div class="line">  std::cin.get(input);</div><div class="line"></div><div class="line">  <span class="comment">// Clean up</span></div><div class="line"> cleanup:</div><div class="line">  <span class="keyword">delete</span> midiin;</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h1><a class="anchor" id="virtual"></a>
Virtual Ports</h1>
<p>The Linux ALSA, Macintosh CoreMIDI and JACK 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#a9484f3af0c0d1c6f255af9b91f55b3e2" title="Create a virtual input port, with optional name, to allow software connections (OS X...">RtMidiIn::openVirtualPort()</a> and <a class="el" href="classRtMidiOut.html#a79d6d672c18463d3759d1523e675f9d3" title="Create a virtual output port, with optional name, to allow software connections (OS X...">RtMidiOut::openVirtualPort()</a> functions. Any messages sent with the <a class="el" href="classRtMidiOut.html#a19c7049a840a0181a0ddd4b14e99c651" 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. The <a class="el" href="classRtMidi.html#a74fc50ce1aec6b8ecb0c31094b3024a9" title="Returns true if a port is open and false if not. ">RtMidi::isPortOpen()</a> function does not report the status of ports created with the <a class="el" href="classRtMidi.html#a2fcf7bceb243f3da51d2322a7a5ae11f" title="Pure virtual openVirtualPort() function. ">RtMidi::openVirtualPort()</a> function.</p>
<h1><a class="anchor" id="compiling"></a>
Compiling</h1>
<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%">
<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>
<tr>
<td>Linux </td><td>ALSA Sequencer </td><td>__LINUX_ALSA__ </td><td><code>asound, pthread</code> </td><td><code>g++ -Wall -D__LINUX_ALSA__ -o midiprobe midiprobe.cpp RtMidi.cpp -lasound -lpthread</code>  </td></tr>
<tr>
<td>Linux or Mac </td><td>JACK MIDI </td><td>__UNIX_JACK__ </td><td><code>jack</code> </td><td><code>g++ -Wall -D__UNIX_JACK__ -o midiprobe midiprobe.cpp RtMidi.cpp -ljack</code>  </td></tr>
<tr>
<td>Macintosh OS X </td><td>CoreMIDI </td><td>__MACOSX_CORE__ </td><td><code>CoreMIDI, CoreAudio, CoreFoundation</code> </td><td><code>g++ -Wall -D__MACOSX_CORE__ -o midiprobe midiprobe.cpp RtMidi.cpp -framework CoreMIDI -framework CoreAudio -framework CoreFoundation</code>  </td></tr>
<tr>
<td>Windows </td><td>Multimedia Library </td><td>__WINDOWS_MM__ </td><td><code>winmm.lib, multithreaded</code> </td><td><em>compiler specific</em>  </td></tr>
</table>
<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.html">RtMidi.h</a></code> and <code>RtMidi.cpp</code> all exist in the same directory.</p>
<h1><a class="anchor" id="debug"></a>
Debugging</h1>
<p>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 define it in <a class="el" href="RtMidi_8h.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>tests</code> directory. The program <code>midiprobe</code> displays the queried capabilities of all MIDI ports found.</p>
<h1><a class="anchor" id="multi"></a>
Using Simultaneous Multiple APIs</h1>
<p>Support for each MIDI API is encapsulated in specific <a class="el" href="classMidiInApi.html">MidiInApi</a> or <a class="el" href="classMidiOutApi.html">MidiOutApi</a> subclasses, making it possible to compile and instantiate multiple API-specific subclasses on a given operating system. For example, one can compile both CoreMIDI and JACK support on the OS-X operating system by providing the appropriate preprocessor definitions for each. In a run-time situation, one might first attempt to determine whether any JACK ports are available. This can be done by specifying the api argument <a class="el" href="classRtMidi.html#aac66af04a85fe5c5f07c360574a19406a1f59daf3120f47c0ae3891773112ddfa">RtMidi::UNIX_JACK</a> when attempting to create an instance of <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>. If no available ports are found, then an instance of <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a> with the api argument <a class="el" href="classRtMidi.html#aac66af04a85fe5c5f07c360574a19406a3f41293f89467641484fbd54c4530908">RtMidi::MACOSX_CORE</a> can be created. Alternately, if no api argument is specified, <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a> will first look for JACK ports and if none are found, then CoreMIDI ports (in linux, the search order is JACK and then ALSA. In theory, it should also be possible to have separate instances of <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a> open at the same time with different underlying API support, though this has not been tested.</p>
<p>The static function <a class="el" href="classRtMidi.html#a025fa339486c9a34b26ec707aa2944ce" title="A static function to determine the available compiled MIDI APIs. ">RtMidi::getCompiledApi()</a> is provided to determine the available compiled API support. The function RtMidi::getCurrentApi() indicates the API selected for a given <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a> instance.</p>
<h1><a class="anchor" id="apinotes"></a>
API Notes</h1>
<p><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.</p>
<h2><a class="anchor" id="linux"></a>
Linux:</h2>
<p><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. Two different MIDI APIs are supported on Linux platforms: <a href="http://www.alsa-project.org/">ALSA</a> and <a href="http://jackit.sourceforge.net/">JACK</a>. A decision was made to not include support for the OSS API because the OSS API provides very limited functionality and because <a href="http://www.alsa-project.org/">ALSA</a> support is now incorporated in the Linux kernel. The ALSA sequencer and JACK APIs allows for virtual software input and output ports.</p>
<h2><a class="anchor" id="macosx"></a>
Macintosh OS X (CoreAudio):</h2>
<p>The Apple CoreMIDI API allows for the establishment of virtual input and output ports to which other software applications can connect.</p>
<p>The <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a> JACK support can be compiled on Macintosh OS-X systems, as well as in Linux.</p>
<h2><a class="anchor" id="windowsds"></a>
Windows (Multimedia Library):</h2>
<p>The <code>configure</code> script provides support for the MinGW compiler.</p>
<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>
<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 but has been tested with Virtual Studio 2010.</p>
<h1><a class="anchor" id="acknowledge"></a>
Development &amp; Acknowledgements</h1>
<p><a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a> is on github (<a href="https://github.com/thestk/rtmidi">https://github.com/thestk/rtmidi</a>). Many thanks to the developers that are helping to maintain and improve <a class="el" href="classRtMidi.html" title="An abstract base class for realtime MIDI input/output. ">RtMidi</a>.</p>
<p>In years past, the following people provided bug fixes and improvements:</p>
<ul>
<li>Stephen Sinclair (Git repo, code and build system)</li>
<li>Atsushi Eno (C API)</li>
<li>Sebastien Alaiwan (JACK memory leaks, Windows kernel streaming)</li>
<li>Jean-Baptiste Berruchon (Windows sysex code)</li>
<li>Pedro Lopez-Cabanillas (ALSA sequencer API, client naming)</li>
<li>Jason Champion (MSW project file for library build)</li>
<li>Eduardo Coutinho (Windows device names)</li>
<li>Paul Dean (increment optimization)</li>
<li>Luc Deschenaux (sysex issues)</li>
<li>John Dey (OS-X timestamps)</li>
<li>Christoph Eckert (ALSA sysex fixes)</li>
<li>Martin Koegler (various fixes)</li>
<li>Immanuel Litzroth (OS-X sysex fix)</li>
<li>Jon McCormack (Snow Leopard updates)</li>
<li>Axel Schmidt (client naming)</li>
<li>Alexander Svetalkin (JACK MIDI)</li>
<li>Casey Tucker (OS-X driver information, sysex sending)</li>
<li>Bastiaan Verreijt (Windows sysex multi-buffer code)</li>
<li>Dan Wilcox</li>
</ul>
<h1><a class="anchor" id="license"></a>
License</h1>
<pre class="fragment">RtMidi: realtime MIDI i/o C++ classes&lt;BR&gt;
Copyright (c) 2003-2017 Gary P. Scavone

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:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

Any person wishing to distribute modifications to the Software is
asked to send the modifications to the original developer so that
they can be incorporated into the canonical version.  This is,
however, not a binding provision of this license.

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.</pre> </div></div><!-- contents -->
<HR>
<table><tr><td><img src="../images/mcgill.gif" width=165></td>
  <td>&copy;2003-2017 Gary P. Scavone, McGill University. All Rights Reserved.<br>
  Maintained by Gary P. Scavone, gary at music.mcgill.ca</td></tr>
</table>
</BODY>
</HTML>