summaryrefslogtreecommitdiff
path: root/doxygen/html/RtMidi_8cpp-source.html
diff options
context:
space:
mode:
Diffstat (limited to 'doxygen/html/RtMidi_8cpp-source.html')
-rwxr-xr-xdoxygen/html/RtMidi_8cpp-source.html482
1 files changed, 482 insertions, 0 deletions
diff --git a/doxygen/html/RtMidi_8cpp-source.html b/doxygen/html/RtMidi_8cpp-source.html
new file mode 100755
index 0000000..1b65b96
--- /dev/null
+++ b/doxygen/html/RtMidi_8cpp-source.html
@@ -0,0 +1,482 @@
+<HTML>
+<HEAD>
+<TITLE>The Synthesis ToolKit in C++ (STK)</TITLE>
+<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
+</HEAD>
+<BODY BGCOLOR="#FFFFFF">
+<CENTER>
+<img src="princeton.gif"> &nbsp; <img src="ccrma.gif"><P>
+<a class="qindex" href="index.html">Home</a> &nbsp; <a class="qindex" href="information.html">Information</a> &nbsp; <a class="qindex" href="classes.html">Classes</a> &nbsp; <a class="qindex" href="download.html">Download</a> &nbsp; <a class="qindex" href="usage.html">Usage</a> &nbsp; <a class="qindex" href="maillist.html">Mail List</a> &nbsp; <a class="qindex" href="system.html">Requirements</a> &nbsp; <a class="qindex" href="links.html">Links</a> &nbsp; <a class="qindex" href="tutorial.html">Tutorial</a></CENTER>
+<HR>
+<!-- Generated by Doxygen 1.3-rc3 -->
+<h1>RtMidi.cpp</h1><div class="fragment"><pre>00001 <span class="comment">/**********************************************************************/</span>
+00010 <span class="comment">/**********************************************************************/</span>
+00011
+00012 <span class="preprocessor">#include "RtMidi.h"</span>
+00013 <span class="preprocessor">#include &lt;sstream&gt;</span>
+00014
+00015 RtMidi :: RtMidi()
+00016 : apiData_( 0 ), connected_( false )
+00017 {
+00018 }
+00019
+00020 <span class="keywordtype">void</span> RtMidi :: error( RtError::Type type )
+00021 {
+00022 <span class="keywordflow">if</span> (type == RtError::WARNING) {
+00023 std::cerr &lt;&lt; <span class="charliteral">'\n'</span> &lt;&lt; errorString_ &lt;&lt; <span class="stringliteral">"\n\n"</span>;
+00024 }
+00025 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (type == RtError::DEBUG_WARNING) {
+00026 <span class="preprocessor">#if defined(__RTMIDI_DEBUG__)</span>
+00027 <span class="preprocessor"></span> std::cerr &lt;&lt; <span class="charliteral">'\n'</span> &lt;&lt; errorString_ &lt;&lt; <span class="stringliteral">"\n\n"</span>;
+00028 <span class="preprocessor">#endif</span>
+00029 <span class="preprocessor"></span> }
+00030 <span class="keywordflow">else</span> {
+00031 std::cerr &lt;&lt; <span class="charliteral">'\n'</span> &lt;&lt; errorString_ &lt;&lt; <span class="stringliteral">"\n\n"</span>;
+00032 <span class="keywordflow">throw</span> <a class="code" href="classRtError.html#a0">RtError</a>( errorString_, type );
+00033 }
+00034 }
+00035
+<a name="l00036"></a><a class="code" href="classRtMidiIn.html#a0">00036</a> <a class="code" href="classRtMidiIn.html#a0">RtMidiIn :: RtMidiIn</a>() : <a class="code" href="classRtMidi.html">RtMidi</a>()
+00037 {
+00038 }
+00039
+<a name="l00040"></a><a class="code" href="classRtMidiIn.html#a1">00040</a> <a class="code" href="classRtMidiIn.html#a0">RtMidiIn :: RtMidiIn</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber, RtMidiCallback callback, <span class="keywordtype">void</span> *userData ) : <a class="code" href="classRtMidi.html">RtMidi</a>()
+00041
+00042 {
+00043 <span class="comment">// Attempt to make the connection.</span>
+00044 this-&gt;<a class="code" href="classRtMidiIn.html#a3">openPort</a>( portNumber, callback, userData );
+00045 }
+00046
+<a name="l00047"></a><a class="code" href="classRtMidiIn.html#a2">00047</a> <a class="code" href="classRtMidiIn.html#a2">RtMidiIn :: ~RtMidiIn</a>()
+00048 {
+00049 <a class="code" href="classRtMidiIn.html#a4">closePort</a>();
+00050 }
+00051
+<a name="l00052"></a><a class="code" href="classRtMidiOut.html#a0">00052</a> <a class="code" href="classRtMidiOut.html#a0">RtMidiOut :: RtMidiOut</a>() : <a class="code" href="classRtMidi.html">RtMidi</a>()
+00053 {
+00054 }
+00055
+<a name="l00056"></a><a class="code" href="classRtMidiOut.html#a1">00056</a> <a class="code" href="classRtMidiOut.html#a0">RtMidiOut :: RtMidiOut</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber ) : <a class="code" href="classRtMidi.html">RtMidi</a>()
+00057 {
+00058 <span class="comment">// Attempt to make the connection.</span>
+00059 this-&gt;<a class="code" href="classRtMidiOut.html#a3">openPort</a>( portNumber );
+00060 }
+00061
+<a name="l00062"></a><a class="code" href="classRtMidiOut.html#a2">00062</a> <a class="code" href="classRtMidiOut.html#a2">RtMidiOut :: ~RtMidiOut</a>()
+00063 {
+00064 <a class="code" href="classRtMidiOut.html#a4">closePort</a>();
+00065 }
+00066
+00067
+00068 <span class="preprocessor">#if defined(__MACOSX_CORE__)</span>
+00069 <span class="preprocessor"></span>
+00070 <span class="comment">// The CoreMIDI API is based on the use of a callback function for</span>
+00071 <span class="comment">// MIDI input. We convert the system specific time stamps to delta</span>
+00072 <span class="comment">// time values.</span>
+00073
+00074 <span class="comment">// OS-X CoreMIDI header files.</span>
+00075 <span class="preprocessor">#include &lt;CoreMIDI/CoreMIDI.h&gt;</span>
+00076 <span class="preprocessor">#include &lt;CoreAudio/HostTime.h&gt;</span>
+00077
+00078 <span class="comment">// A structure to hold variables related to the CoreMIDI API</span>
+00079 <span class="comment">// implementation.</span>
+00080 <span class="keyword">struct </span>CoreMidiData {
+00081 MIDIClientRef client;
+00082 MIDIPortRef port;
+00083 MIDIEndpointRef destinationId;
+00084 };
+00085
+00086 <span class="keywordtype">void</span> midiInputCallback( <span class="keyword">const</span> MIDIPacketList *list, <span class="keywordtype">void</span> *procRef, <span class="keywordtype">void</span> *srcRef )
+00087 {
+00088 RtMidiIn::RtMidiInData *data = static_cast&lt;RtMidiIn::RtMidiInData *&gt; (procRef);
+00089
+00090 <span class="keywordtype">bool</span> continueSysex = <span class="keyword">false</span>;
+00091 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> status;
+00092 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> nBytes, iByte, size;
+00093 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <span class="keywordtype">long</span> time;
+00094 RtMidiIn::MidiMessage message;
+00095 <span class="keyword">const</span> MIDIPacket *packet = &amp;list-&gt;packet[0];
+00096 <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;list-&gt;numPackets; ++i ) {
+00097
+00098 <span class="comment">// My interpretation of the CoreMIDI documentation: all message</span>
+00099 <span class="comment">// types, except sysex, are complete within a packet and there may</span>
+00100 <span class="comment">// be several of them in a single packet. Sysex messages can be</span>
+00101 <span class="comment">// broken across multiple packets but are bundled alone within a</span>
+00102 <span class="comment">// packet. I'm assuming that sysex messages, if segmented, must</span>
+00103 <span class="comment">// be complete within the same MIDIPacketList.</span>
+00104
+00105 nBytes = packet-&gt;length;
+00106 <span class="keywordflow">if</span> ( nBytes == 0 ) <span class="keywordflow">continue</span>;
+00107
+00108 <span class="comment">// Calculate time stamp.</span>
+00109 message.timeStamp = 0.0;
+00110 time = packet-&gt;timeStamp;
+00111 time -= data-&gt;lastTime;
+00112 data-&gt;lastTime = packet-&gt;timeStamp;
+00113 time = AudioConvertHostTimeToNanos( time );
+00114 message.timeStamp = time * 0.000000001;
+00115
+00116 iByte = 0;
+00117 <span class="keywordflow">if</span> ( continueSysex ) {
+00118 <span class="comment">// We have a continuing, segmented sysex message.</span>
+00119 <span class="keywordflow">if</span> ( !(data-&gt;ignoreFlags &amp; 0x01) ) {
+00120 <span class="comment">// If we're not ignoring sysex messages, copy the entire packet.</span>
+00121 message.bytes.assign( packet-&gt;data, &amp;packet-&gt;data[nBytes] );
+00122 }
+00123 <span class="keywordflow">if</span> ( packet-&gt;data[nBytes] == 0xF7 ) continueSysex = <span class="keyword">false</span>;
+00124 <span class="keywordflow">if</span> ( !continueSysex ) {
+00125 <span class="comment">// If not a continuing sysex message, invoke the user callback function or queue the message.</span>
+00126 <span class="keywordflow">if</span> ( data-&gt;usingCallback &amp;&amp; message.bytes.size() &gt; 0 ) {
+00127 <a class="code" href="classRtMidiIn.html#s0">RtMidiIn::RtMidiCallback</a> callback = (RtMidiIn::RtMidiCallback) data-&gt;userCallback;
+00128 callback( message.timeStamp, &amp;message.bytes, data-&gt;userData );
+00129 }
+00130 <span class="keywordflow">else</span> {
+00131 <span class="comment">// As long as we haven't reached our queue size limit, push the message.</span>
+00132 <span class="keywordflow">if</span> ( data-&gt;queueLimit &gt; data-&gt;queue.size() )
+00133 data-&gt;queue.push( message );
+00134 <span class="keywordflow">else</span>
+00135 std::cerr &lt;&lt; <span class="stringliteral">"\nRtMidiIn: message queue limit reached!!\n\n"</span>;
+00136 }
+00137 message.bytes.clear();
+00138 }
+00139 }
+00140 <span class="keywordflow">else</span> {
+00141 <span class="keywordflow">while</span> ( iByte &lt; nBytes ) {
+00142 size = 0;
+00143 <span class="comment">// We are expecting that the next byte in the packet is a status byte.</span>
+00144 status = packet-&gt;data[iByte];
+00145 <span class="keywordflow">if</span> ( !(status &amp; 0x80) ) <span class="keywordflow">break</span>;
+00146 <span class="comment">// Determine the number of bytes in the MIDI message.</span>
+00147 <span class="keywordflow">if</span> ( status &lt; 0xC0 ) size = 3;
+00148 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( status &lt; 0xE0 ) size = 2;
+00149 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( status &lt; 0xF0 ) size = 3;
+00150 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( status == 0xF0 ) {
+00151 <span class="comment">// A MIDI sysex</span>
+00152 <span class="keywordflow">if</span> ( data-&gt;ignoreFlags &amp; 0x01 ) {
+00153 size = 0;
+00154 iByte = nBytes;
+00155 }
+00156 <span class="keywordflow">else</span> size = nBytes - iByte;
+00157 <span class="keywordflow">if</span> ( packet-&gt;data[nBytes] == 0xF7 ) continueSysex = <span class="keyword">false</span>;
+00158 }
+00159 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( status &lt; 0xF3 ) {
+00160 <span class="keywordflow">if</span> ( status == 0xF1 &amp;&amp; (data-&gt;ignoreFlags &amp; 0x02) ) {
+00161 <span class="comment">// A MIDI time code message and we're ignoring it.</span>
+00162 size = 0;
+00163 iByte += 3;
+00164 }
+00165 <span class="keywordflow">else</span> size = 3;
+00166 }
+00167 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( status == 0xF3 ) size = 2;
+00168 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( status == 0xFE &amp;&amp; (data-&gt;ignoreFlags &amp; 0x04) ) {
+00169 <span class="comment">// A MIDI active sensing message and we're ignoring it.</span>
+00170 size = 0;
+00171 iByte += 1;
+00172 }
+00173 <span class="keywordflow">else</span> size = 1;
+00174
+00175 <span class="comment">// Copy the MIDI data to our vector.</span>
+00176 <span class="keywordflow">if</span> ( size ) {
+00177 message.bytes.assign( &amp;packet-&gt;data[iByte], &amp;packet-&gt;data[iByte+size] );
+00178 <span class="keywordflow">if</span> ( !continueSysex ) {
+00179 <span class="comment">// If not a continuing sysex message, invoke the user callback function or queue the message.</span>
+00180 <span class="keywordflow">if</span> ( data-&gt;usingCallback ) {
+00181 <a class="code" href="classRtMidiIn.html#s0">RtMidiIn::RtMidiCallback</a> callback = (RtMidiIn::RtMidiCallback) data-&gt;userCallback;
+00182 callback( message.timeStamp, &amp;message.bytes, data-&gt;userData );
+00183 }
+00184 <span class="keywordflow">else</span> {
+00185 <span class="comment">// As long as we haven't reached our queue size limit, push the message.</span>
+00186 <span class="keywordflow">if</span> ( data-&gt;queueLimit &gt; data-&gt;queue.size() )
+00187 data-&gt;queue.push( message );
+00188 <span class="keywordflow">else</span>
+00189 std::cerr &lt;&lt; <span class="stringliteral">"\nRtMidiIn: message queue limit reached!!\n\n"</span>;
+00190 }
+00191 message.bytes.clear();
+00192 }
+00193 iByte += size;
+00194 }
+00195 }
+00196 }
+00197 packet = MIDIPacketNext(packet);
+00198 }
+00199 }
+00200
+00201 <span class="keywordtype">void</span> <a class="code" href="classRtMidiIn.html#a3">RtMidiIn :: openPort</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber, RtMidiCallback callback, <span class="keywordtype">void</span> *userData )
+00202 {
+00203 <span class="keywordflow">if</span> ( connected_ ) {
+00204 errorString_ = <span class="stringliteral">"RtMidiIn::openPort: a valid connection already exists!"</span>;
+00205 error( RtError::WARNING );
+00206 <span class="keywordflow">return</span>;
+00207 }
+00208
+00209 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nSrc = MIDIGetNumberOfSources();
+00210 <span class="keywordflow">if</span> (nSrc &lt; 1) {
+00211 errorString_ = <span class="stringliteral">"RtMidiIn::openPort: no MIDI input sources found!"</span>;
+00212 error( RtError::NO_DEVICES_FOUND );
+00213 }
+00214
+00215 std::ostringstream ost;
+00216 <span class="keywordflow">if</span> ( portNumber &gt;= nSrc ) {
+00217 ost &lt;&lt; <span class="stringliteral">"RtMidiIn::openPort: the 'portNumber' argument ("</span> &lt;&lt; portNumber &lt;&lt; <span class="stringliteral">") is invalid."</span>;
+00218 errorString_ = ost.str();
+00219 error( RtError::INVALID_PARAMETER );
+00220 }
+00221
+00222 MIDIClientRef client;
+00223 OSStatus result = MIDIClientCreate( CFSTR(<span class="stringliteral">"RtMidi Input Client"</span>), NULL, NULL, &amp;client );
+00224 <span class="keywordflow">if</span> ( result != noErr ) {
+00225 errorString_ = <span class="stringliteral">"RtMidiIn::openPort: error creating OS-X MIDI client object."</span>;
+00226 error( RtError::DRIVER_ERROR );
+00227 }
+00228
+00229 MIDIPortRef port;
+00230 result = MIDIInputPortCreate( client, CFSTR(<span class="stringliteral">"RtMidi Virtual MIDI Input Port"</span>), midiInputCallback, (<span class="keywordtype">void</span> *)&amp;inputData_, &amp;port );
+00231 <span class="keywordflow">if</span> ( result != noErr ) {
+00232 MIDIClientDispose( client );
+00233 errorString_ = <span class="stringliteral">"RtMidiIn::openPort: error creating OS-X MIDI input port."</span>;
+00234 error( RtError::DRIVER_ERROR );
+00235 }
+00236
+00237 <span class="comment">// Get the desired input source identifier.</span>
+00238 MIDIEndpointRef src = MIDIGetSource( portNumber );
+00239 <span class="keywordflow">if</span> ( src == NULL ) {
+00240 MIDIPortDispose( port );
+00241 MIDIClientDispose( client );
+00242 errorString_ = <span class="stringliteral">"RtMidiIn::openPort: error getting MIDI input source reference."</span>;
+00243 error( RtError::DRIVER_ERROR );
+00244 }
+00245
+00246 <span class="comment">// Make the connection.</span>
+00247 result = MIDIPortConnectSource(port, src, NULL );
+00248 <span class="keywordflow">if</span> ( result != noErr ) {
+00249 MIDIPortDispose( port );
+00250 MIDIClientDispose( client );
+00251 errorString_ = <span class="stringliteral">"RtMidiIn::openPort: error connecting OS-X MIDI input port."</span>;
+00252 error( RtError::DRIVER_ERROR );
+00253 }
+00254
+00255 <span class="comment">// Save our api-specific connection information.</span>
+00256 CoreMidiData *data = (CoreMidiData *) <span class="keyword">new</span> CoreMidiData;
+00257 data-&gt;client = client;
+00258 data-&gt;port = port;
+00259 apiData_ = (<span class="keywordtype">void</span> *) data;
+00260
+00261 <span class="keywordflow">if</span> ( callback ) {
+00262 inputData_.userCallback = (<span class="keywordtype">void</span> *) callback;
+00263 inputData_.userData = userData;
+00264 inputData_.usingCallback = <span class="keyword">true</span>;
+00265 }
+00266
+00267 inputData_.lastTime = AudioGetCurrentHostTime();
+00268
+00269 connected_ = <span class="keyword">true</span>;
+00270 }
+00271
+00272 <span class="keywordtype">void</span> <a class="code" href="classRtMidiIn.html#a4">RtMidiIn :: closePort</a>( <span class="keywordtype">void</span> )
+00273 {
+00274 <span class="keywordflow">if</span> ( connected_ ) {
+00275 CoreMidiData *data = static_cast&lt;CoreMidiData *&gt; (apiData_);
+00276 MIDIClientDispose( data-&gt;client );
+00277 MIDIPortDispose( data-&gt;port );
+00278 <span class="keyword">delete</span> data;
+00279 apiData_ = 0;
+00280 }
+00281
+00282 connected_ = <span class="keyword">false</span>;
+00283 }
+00284
+00285 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classRtMidiIn.html#a5">RtMidiIn :: getPortCount</a>()
+00286 {
+00287 <span class="keywordflow">return</span> MIDIGetNumberOfSources();
+00288 }
+00289
+00290 std::string <a class="code" href="classRtMidiIn.html#a6">RtMidiIn :: getPortName</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber )
+00291 {
+00292 CFStringRef nameRef;
+00293 MIDIEndpointRef portRef;
+00294 std::ostringstream ost;
+00295 <span class="keywordtype">char</span> name[128];
+00296
+00297 <span class="keywordflow">if</span> ( portNumber &gt;= MIDIGetNumberOfSources() ) {
+00298 ost &lt;&lt; <span class="stringliteral">"RtMidiIn::getPortName: the 'portNumber' argument ("</span> &lt;&lt; portNumber &lt;&lt; <span class="stringliteral">") is invalid."</span>;
+00299 errorString_ = ost.str();
+00300 error( RtError::INVALID_PARAMETER );
+00301 }
+00302 portRef = MIDIGetSource( portNumber );
+00303
+00304 MIDIObjectGetStringProperty( portRef, kMIDIPropertyName, &amp;nameRef );
+00305 CFStringGetCString( nameRef, name, <span class="keyword">sizeof</span>(name), 0);
+00306 CFRelease( nameRef );
+00307 std::string stringName = name;
+00308 <span class="keywordflow">return</span> stringName;
+00309 }
+00310
+00311 <span class="keywordtype">void</span> <a class="code" href="classRtMidiIn.html#a7">RtMidiIn :: setQueueSizeLimit</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> queueSize )
+00312 {
+00313 inputData_.queueLimit = queueSize;
+00314 }
+00315
+00316 <span class="keywordtype">void</span> <a class="code" href="classRtMidiIn.html#a8">RtMidiIn :: ignoreTypes</a>( <span class="keywordtype">bool</span> midiSysex, <span class="keywordtype">bool</span> midiTime, <span class="keywordtype">bool</span> midiSense )
+00317 {
+00318 inputData_.ignoreFlags = 0;
+00319 <span class="keywordflow">if</span> ( midiSysex ) inputData_.ignoreFlags = 0x01;
+00320 <span class="keywordflow">if</span> ( midiTime ) inputData_.ignoreFlags |= 0x02;
+00321 <span class="keywordflow">if</span> ( midiSense ) inputData_.ignoreFlags |= 0x04;
+00322 }
+00323
+00324 <span class="keywordtype">double</span> <a class="code" href="classRtMidiIn.html#a9">RtMidiIn :: getMessage</a>( std::vector&lt;unsigned char&gt; *message )
+00325 {
+00326 message-&gt;clear();
+00327 <span class="keywordflow">if</span> ( !connected_ ) {
+00328 errorString_ = <span class="stringliteral">"RtMidiIn::getNextMessage: a port is not open!"</span>;
+00329 error( RtError::WARNING );
+00330 <span class="keywordflow">return</span> 0.0;
+00331 }
+00332
+00333 <span class="keywordflow">if</span> ( inputData_.usingCallback ) {
+00334 errorString_ = <span class="stringliteral">"RtMidiIn::getNextMessage: a user callback is currently set for this port."</span>;
+00335 error( RtError::WARNING );
+00336 <span class="keywordflow">return</span> 0.0;
+00337 }
+00338
+00339 <span class="keywordflow">if</span> ( inputData_.queue.size() == 0 ) <span class="keywordflow">return</span> 0.0;
+00340
+00341 <span class="comment">// Copy queued message to the vector pointer argument and then "pop" it.</span>
+00342 std::vector&lt;unsigned char&gt; *bytes = &amp;(inputData_.queue.front().bytes);
+00343 message-&gt;assign( bytes-&gt;begin(), bytes-&gt;end() );
+00344 <span class="keywordtype">double</span> deltaTime = inputData_.queue.front().timeStamp;
+00345 inputData_.queue.pop();
+00346
+00347 <span class="keywordflow">return</span> deltaTime;
+00348 }
+00349
+00350 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classRtMidiOut.html#a5">RtMidiOut :: getPortCount</a>()
+00351 {
+00352 <span class="keywordflow">return</span> MIDIGetNumberOfDestinations();
+00353 }
+00354
+00355 std::string <a class="code" href="classRtMidiOut.html#a6">RtMidiOut :: getPortName</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber )
+00356 {
+00357 CFStringRef nameRef;
+00358 MIDIEndpointRef portRef;
+00359 std::ostringstream ost;
+00360 <span class="keywordtype">char</span> name[128];
+00361
+00362 <span class="keywordflow">if</span> ( portNumber &gt;= MIDIGetNumberOfDestinations() ) {
+00363 ost &lt;&lt; <span class="stringliteral">"RtMidiOut::getPortName: the 'portNumber' argument ("</span> &lt;&lt; portNumber &lt;&lt; <span class="stringliteral">") is invalid."</span>;
+00364 errorString_ = ost.str();
+00365 error( RtError::INVALID_PARAMETER );
+00366 }
+00367 portRef = MIDIGetDestination( portNumber );
+00368
+00369 MIDIObjectGetStringProperty( portRef, kMIDIPropertyName, &amp;nameRef );
+00370 CFStringGetCString( nameRef, name, <span class="keyword">sizeof</span>(name), 0);
+00371 CFRelease( nameRef );
+00372 std::string stringName = name;
+00373 <span class="keywordflow">return</span> stringName;
+00374 }
+00375
+00376 <span class="keywordtype">void</span> <a class="code" href="classRtMidiOut.html#a3">RtMidiOut :: openPort</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber )
+00377 {
+00378 <span class="keywordflow">if</span> ( connected_ ) {
+00379 errorString_ = <span class="stringliteral">"RtMidiOut::openPort: a valid connection already exists!"</span>;
+00380 error( RtError::WARNING );
+00381 <span class="keywordflow">return</span>;
+00382 }
+00383
+00384 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nDest = MIDIGetNumberOfDestinations();
+00385 <span class="keywordflow">if</span> (nDest &lt; 1) {
+00386 errorString_ = <span class="stringliteral">"RtMidiOut::openPort: no MIDI output destinations found!"</span>;
+00387 error( RtError::NO_DEVICES_FOUND );
+00388 }
+00389
+00390 std::ostringstream ost;
+00391 <span class="keywordflow">if</span> ( portNumber &gt;= nDest ) {
+00392 ost &lt;&lt; <span class="stringliteral">"RtMidiOut::openPort: the 'portNumber' argument ("</span> &lt;&lt; portNumber &lt;&lt; <span class="stringliteral">") is invalid."</span>;
+00393 errorString_ = ost.str();
+00394 error( RtError::INVALID_PARAMETER );
+00395 }
+00396
+00397 MIDIClientRef client;
+00398 OSStatus result = MIDIClientCreate( CFSTR(<span class="stringliteral">"RtMidi Output Client"</span>), NULL, NULL, &amp;client );
+00399 <span class="keywordflow">if</span> ( result != noErr ) {
+00400 errorString_ = <span class="stringliteral">"RtMidiOut::openPort: error creating OS-X MIDI client object."</span>;
+00401 error( RtError::DRIVER_ERROR );
+00402 }
+00403
+00404 MIDIPortRef port;
+00405 result = MIDIOutputPortCreate( client, CFSTR(<span class="stringliteral">"RtMidi Virtual MIDI Output Port"</span>), &amp;port );
+00406 <span class="keywordflow">if</span> ( result != noErr ) {
+00407 MIDIClientDispose( client );
+00408 errorString_ = <span class="stringliteral">"RtMidiOut::openPort: error creating OS-X MIDI output port."</span>;
+00409 error( RtError::DRIVER_ERROR );
+00410 }
+00411
+00412 <span class="comment">// Get the desired output port identifier.</span>
+00413 MIDIEndpointRef destinationId = MIDIGetDestination( portNumber );
+00414 <span class="keywordflow">if</span> ( destinationId == NULL ) {
+00415 MIDIPortDispose( port );
+00416 MIDIClientDispose( client );
+00417 errorString_ = <span class="stringliteral">"RtMidiOut::openPort: error getting MIDI output destination reference."</span>;
+00418 error( RtError::DRIVER_ERROR );
+00419 }
+00420
+00421 <span class="comment">// Save our api-specific connection information.</span>
+00422 CoreMidiData *data = (CoreMidiData *) <span class="keyword">new</span> CoreMidiData;
+00423 data-&gt;client = client;
+00424 data-&gt;port = port;
+00425 data-&gt;destinationId = destinationId;
+00426 apiData_ = (<span class="keywordtype">void</span> *) data;
+00427
+00428 connected_ = <span class="keyword">true</span>;
+00429 }
+00430
+00431 <span class="keywordtype">void</span> <a class="code" href="classRtMidiOut.html#a4">RtMidiOut :: closePort</a>( <span class="keywordtype">void</span> )
+00432 {
+00433 <span class="keywordflow">if</span> ( connected_ ) {
+00434 CoreMidiData *data = static_cast&lt;CoreMidiData *&gt; (apiData_);
+00435 MIDIClientDispose( data-&gt;client );
+00436 MIDIPortDispose( data-&gt;port );
+00437 <span class="keyword">delete</span> data;
+00438 apiData_ = 0;
+00439 }
+00440
+00441 connected_ = <span class="keyword">false</span>;
+00442 }
+00443
+00444 <span class="keywordtype">void</span> <a class="code" href="classRtMidiOut.html#a7">RtMidiOut :: sendMessage</a>( std::vector&lt;unsigned char&gt; *message )
+00445 {
+00446 <span class="keywordflow">if</span> ( !connected_ ) {
+00447 errorString_ = <span class="stringliteral">"RtMidiOut::sendMessage: a port is not open!"</span>;
+00448 error( RtError::WARNING );
+00449 <span class="keywordflow">return</span>;
+00450 }
+00451
+00452 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nBytes = message-&gt;size();
+00453 <span class="comment">// Pad the buffer for extra (unknown) structure data.</span>
+00454 Byte buffer[nBytes+32];
+00455 MIDIPacketList *pktlist = (MIDIPacketList *) buffer;
+00456 MIDIPacket *curPacket = MIDIPacketListInit( pktlist );
+00457
+00458 MIDITimeStamp timeStamp = 0;
+00459 curPacket = MIDIPacketListAdd( pktlist, <span class="keyword">sizeof</span>(buffer), curPacket, timeStamp, nBytes, &amp;message-&gt;at(0) );
+00460
+00461 CoreMidiData *data = static_cast&lt;CoreMidiData *&gt; (apiData_);
+00462 OSStatus result = MIDISend( data-&gt;port, data-&gt;destinationId, pktlist );
+00463 <span class="keywordflow">if</span> ( result != noErr ) {
+00464 errorString_ = <span class="stringliteral">"RtMidiOut::sendMessage: error sending MIDI message."</span>;
+00465 error( RtError::WARNING );
+00466 }
+00467 }
+00468
+00469 <span class="preprocessor">#endif</span>
+00470 <span class="preprocessor"></span>
+</pre></div><HR>
+
+<table>
+ <tr><td><A HREF="http://www-ccrma.stanford.edu/software/stk/"><I>The Synthesis ToolKit in C++ (STK)</I></A></td></tr>
+ <tr><td>&copy;1995-2002 Perry R. Cook and Gary P. Scavone. All Rights Reserved.</td></tr>
+</table>
+
+</BODY>
+</HTML>