diff options
Diffstat (limited to 'doxygen/html/oldRtMidi_8cpp-source.html')
| -rwxr-xr-x | doxygen/html/oldRtMidi_8cpp-source.html | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/doxygen/html/oldRtMidi_8cpp-source.html b/doxygen/html/oldRtMidi_8cpp-source.html new file mode 100755 index 0000000..90c3f47 --- /dev/null +++ b/doxygen/html/oldRtMidi_8cpp-source.html @@ -0,0 +1,385 @@ +<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"> <img src="ccrma.gif"><P>
+<a class="qindex" href="index.html">Home</a> <a class="qindex" href="information.html">Information</a> <a class="qindex" href="classes.html">Classes</a> <a class="qindex" href="download.html">Download</a> <a class="qindex" href="usage.html">Usage</a> <a class="qindex" href="maillist.html">Mail List</a> <a class="qindex" href="system.html">Requirements</a> <a class="qindex" href="links.html">Links</a> <a class="qindex" href="tutorial.html">Tutorial</a></CENTER>
+<HR>
+<!-- Generated by Doxygen 1.3-rc3 -->
+<h1>oldRtMidi.cpp</h1><div class="fragment"><pre>00001 <span class="comment">// RtMidi class declaration</span>
+00002 <span class="comment">// Realtime MIDI input/output class.</span>
+00003 <span class="comment">//</span>
+00004 <span class="comment">// This class provides access to a single MIDI input or output port.</span>
+00005 <span class="comment">// Create multiple instances of this class to connect to more than</span>
+00006 <span class="comment">// one MIDI device at the same time.</span>
+00007 <span class="comment">//</span>
+00008 <span class="comment">// by Gary P. Scavone, 2003.</span>
+00009
+00010 <span class="preprocessor">#include "RtMidi.h"</span>
+00011 <span class="preprocessor">#include <sstream></span>
+00012 <span class="preprocessor">#include <sys/time.h></span>
+00013
+00014 <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 )
+00015 {
+00016 RtMidi::RtMidiCallbackInfo *info = static_cast<RtMidi::RtMidiCallbackInfo *> (procRef);
+00017
+00018 RtMidi::MidiMessage *message;
+00019 <span class="keyword">const</span> MIDIPacket *packet = &list->packet[0];
+00020 <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i<list->numPackets; ++i ) {
+00021
+00022 <span class="comment">// For the moment, we're limiting ourselves to basic MIDI messages</span>
+00023 <span class="comment">// and ignoring the (real) possibility that multiple MIDI messages</span>
+00024 <span class="comment">// can be packed into a single MIDIPacket. FIXME!!!</span>
+00025 <span class="keywordflow">if</span> ( packet->length > 3 ) <span class="keywordflow">continue</span>;
+00026
+00027 message = static_cast<RtMidi::MidiMessage *> (&info->buffer[info->writeIndex++]);
+00028 message->bytes.assign( packet->data, &packet->data[packet->length] );
+00029
+00030 <span class="comment">// - have status byte:</span>
+00031 <span class="comment">// - look for subsequent data bytes of known number (unless sysex ... unknown number)</span>
+00032 <span class="comment">// - if find a system realtime:</span>
+00033 <span class="comment">// - copy incomplete message to next buffer</span>
+00034 <span class="comment">// - clear current buffer and write realtime message</span>
+00035 <span class="comment">// - continue parsing data bytes</span>
+00036 <span class="comment">// while !finished parsing:</span>
+00037 <span class="comment">// if data byte</span>
+00038 <span class="comment">// if ( incomplete ) {</span>
+00039 <span class="comment">// for ( int i = 0; i < packet->length; i++ ) {</span>
+00040 <span class="comment">// if while ( packet->data[</span>
+00041 <span class="comment">// }</span>
+00042 <span class="comment">//}</span>
+00043
+00044 <span class="comment">// Calculate time stamp.</span>
+00045 message->timeStamp = 0.0;
+00046 <span class="keywordflow">if</span> ( info->doDeltaTime ) {
+00047 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> time = packet->timeStamp;
+00048 time -= info->lastTime;
+00049 info->lastTime = packet->timeStamp;
+00050 time = AudioConvertHostTimeToNanos( time );
+00051 message->timeStamp = time * 0.000000001;
+00052 }
+00053 <span class="keywordflow">else</span> { <span class="comment">// absolute time in seconds since midnight (0 hour), January 1, 1970</span>
+00054 timeval time;
+00055 <span class="keywordflow">if</span> ( gettimeofday( &time, NULL ) != 0 ) {
+00056 std::cerr << <span class="stringliteral">"RtMidi: error in midiInputCallback calculating time stamp."</span>;
+00057 }
+00058 <span class="keywordflow">else</span> {
+00059 message->timeStamp = (double) time.tv_sec;
+00060 message->timeStamp += (double) (time.tv_usec * 0.000001);
+00061 }
+00062 }
+00063
+00064 <span class="keywordflow">if</span> ( info->writeIndex >= nMessages )
+00065 info->writeIndex = 0;
+00066
+00067 <span class="keywordflow">if</span> ( info->usingCallback ) {
+00068 <a class="code" href="classRtMidi.html#s0">RtMidi::RtMidiCallback</a> callback = (RtMidi::RtMidiCallback) info->userCallback;
+00069 callback( message, info->userData );
+00070 }
+00071
+00072 packet = MIDIPacketNext(packet);
+00073 }
+00074 }
+00075
+00076 <a class="code" href="classRtMidi.html#a0">RtMidi :: RtMidi</a>( TimeType time )
+00077 {
+00078 <span class="keywordflow">if</span> ( time == ABSOLUTE_TIME ) callbackInfo_.doDeltaTime = <span class="keyword">false</span>;
+00079 callbackInfo_.lastTime = AudioGetCurrentHostTime();
+00080 readIndex_ = 0;
+00081 connected_ = <span class="keyword">false</span>;
+00082 }
+00083
+00084 <a class="code" href="classRtMidi.html#a0">RtMidi :: RtMidi</a>( PortType type, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber, TimeType time )
+00085 {
+00086 <span class="keywordflow">if</span> ( time == ABSOLUTE_TIME ) callbackInfo_.doDeltaTime = <span class="keyword">false</span>;
+00087 callbackInfo_.lastTime = AudioGetCurrentHostTime();
+00088 readIndex_ = 0;
+00089 connected_ = <span class="keyword">false</span>;
+00090
+00091 <span class="comment">// Attempt to make the connection.</span>
+00092 this-><a class="code" href="classRtMidi.html#a3">openPort</a>( type, portNumber );
+00093 }
+00094
+<a name="l00095"></a><a class="code" href="classRtMidi.html#a2">00095</a> <a class="code" href="classRtMidi.html#a2">RtMidi :: ~RtMidi</a>()
+00096 {
+00097 <span class="keywordflow">if</span> ( connected_ ) {
+00098 MIDIClientDispose( client_ );
+00099 MIDIPortDispose( port_ );
+00100 }
+00101 }
+00102
+<a name="l00103"></a><a class="code" href="classRtMidi.html#a3">00103</a> <span class="keywordtype">void</span> <a class="code" href="classRtMidi.html#a3">RtMidi :: openPort</a>( PortType type, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber )
+00104 {
+00105 <span class="keywordflow">if</span> ( connected_ ) {
+00106 errorString_ = <span class="stringliteral">"RtMidi::openPort: a valid connection already exists."</span>;
+00107 error( RtError::WARNING );
+00108 <span class="keywordflow">return</span>;
+00109 }
+00110
+00111 <span class="keywordflow">if</span> ( portNumber < 0 ) {
+00112 errorString_ = <span class="stringliteral">"RtMidi::openPort: the 'portNumber' argument must be greater than zero."</span>;
+00113 error( RtError::INVALID_PARAMETER );
+00114 }
+00115
+00116 std::ostringstream ost;
+00117 <span class="keywordflow">if</span> ( type == MIDI_INPUT ) {
+00118 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nSrc = MIDIGetNumberOfSources();
+00119 <span class="keywordflow">if</span> (nSrc < 1) {
+00120 errorString_ = <span class="stringliteral">"RtMidi::openPort: no MIDI input sources found!"</span>;
+00121 error( RtError::NO_DEVICES_FOUND );
+00122 }
+00123
+00124 <span class="keywordflow">if</span> ( portNumber >= nSrc ) {
+00125 ost << <span class="stringliteral">"RtMidi::openPort: the 'portNumber' argument ("</span> << portNumber << <span class="stringliteral">") is invalid."</span>;
+00126 errorString_ = ost.str();
+00127 error( RtError::INVALID_PARAMETER );
+00128 }
+00129
+00130 OSStatus result = MIDIClientCreate( CFSTR(<span class="stringliteral">"RtMidi Input Client"</span>), NULL, NULL, &client_ );
+00131 <span class="keywordflow">if</span> ( result != noErr ) {
+00132 errorString_ = <span class="stringliteral">"RtMidi::openPort: error creating OS-X MIDI client object."</span>;
+00133 error( RtError::DRIVER_ERROR );
+00134 }
+00135
+00136 result = MIDIInputPortCreate( client_, CFSTR(<span class="stringliteral">"RtMidi Virtual MIDI Input Port"</span>), midiInputCallback, (<span class="keywordtype">void</span> *)&callbackInfo_, &port_ );
+00137 <span class="keywordflow">if</span> ( result != noErr ) {
+00138 MIDIClientDispose( client_ );
+00139 errorString_ = <span class="stringliteral">"RtMidi::openPort: error creating OS-X MIDI input port."</span>;
+00140 error( RtError::DRIVER_ERROR );
+00141 }
+00142
+00143 <span class="comment">// Get the desired input source identifier.</span>
+00144 MIDIEndpointRef src = MIDIGetSource( portNumber );
+00145 <span class="keywordflow">if</span> ( src == NULL ) {
+00146 MIDIPortDispose( port_ );
+00147 MIDIClientDispose( client_ );
+00148 errorString_ = <span class="stringliteral">"RtMidi::openPort: error getting MIDI input source reference."</span>;
+00149 error( RtError::DRIVER_ERROR );
+00150 }
+00151
+00152 <span class="comment">// Make the connection.</span>
+00153 result = MIDIPortConnectSource(port_, src, NULL );
+00154 <span class="keywordflow">if</span> ( result != noErr ) {
+00155 MIDIPortDispose( port_ );
+00156 MIDIClientDispose( client_ );
+00157 errorString_ = <span class="stringliteral">"RtMidi::openPort: error connecting OS-X MIDI input port."</span>;
+00158 error( RtError::DRIVER_ERROR );
+00159 }
+00160
+00161 isInputPort_ = <span class="keyword">true</span>;
+00162 callbackInfo_.lastTime = AudioGetCurrentHostTime();
+00163 }
+00164 <span class="keywordflow">else</span> { <span class="comment">// MIDI_OUTPUT</span>
+00165 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nDest = MIDIGetNumberOfDestinations();
+00166 <span class="keywordflow">if</span> (nDest < 1) {
+00167 errorString_ = <span class="stringliteral">"RtMidi::openPort: no MIDI output destinations found!"</span>;
+00168 error( RtError::NO_DEVICES_FOUND );
+00169 }
+00170
+00171 <span class="keywordflow">if</span> ( portNumber >= nDest ) {
+00172 ost << <span class="stringliteral">"RtMidi::openPort: the 'portNumber' argument ("</span> << portNumber << <span class="stringliteral">") is invalid."</span>;
+00173 errorString_ = ost.str();
+00174 error( RtError::INVALID_PARAMETER );
+00175 }
+00176
+00177 OSStatus result = MIDIClientCreate( CFSTR(<span class="stringliteral">"RtMidi Output Client"</span>), NULL, NULL, &client_ );
+00178 <span class="keywordflow">if</span> ( result != noErr ) {
+00179 errorString_ = <span class="stringliteral">"RtMidi::openPort: error creating OS-X MIDI client object."</span>;
+00180 error( RtError::DRIVER_ERROR );
+00181 }
+00182
+00183 result = MIDIOutputPortCreate( client_, CFSTR(<span class="stringliteral">"RtMidi Virtual MIDI Output Port"</span>), &port_ );
+00184 <span class="keywordflow">if</span> ( result != noErr ) {
+00185 MIDIClientDispose( client_ );
+00186 errorString_ = <span class="stringliteral">"RtMidi::openPort: error creating OS-X MIDI output port."</span>;
+00187 error( RtError::DRIVER_ERROR );
+00188 }
+00189
+00190 <span class="comment">// Get the desired output port identifier.</span>
+00191 destinationId_ = MIDIGetDestination( portNumber );
+00192 <span class="keywordflow">if</span> ( destinationId_ == NULL ) {
+00193 MIDIPortDispose( port_ );
+00194 MIDIClientDispose( client_ );
+00195 errorString_ = <span class="stringliteral">"RtMidi::openPort: error getting MIDI output destination reference."</span>;
+00196 error( RtError::DRIVER_ERROR );
+00197 }
+00198
+00199 isInputPort_ = <span class="keyword">false</span>;
+00200 }
+00201
+00202 connected_ = <span class="keyword">true</span>;
+00203 }
+00204
+<a name="l00205"></a><a class="code" href="classRtMidi.html#a4">00205</a> <span class="keywordtype">void</span> <a class="code" href="classRtMidi.html#a4">RtMidi :: closePort</a>( <span class="keywordtype">void</span> )
+00206 {
+00207 <span class="keywordflow">if</span> ( connected_ ) {
+00208 MIDIClientDispose( client_ );
+00209 MIDIPortDispose( port_ );
+00210 }
+00211 <span class="keywordflow">else</span> {
+00212 errorString_ = <span class="stringliteral">"RtMidi::closePort: a port connection was not open!"</span>;
+00213 error( RtError::WARNING );
+00214 }
+00215 connected_ = <span class="keyword">false</span>;
+00216 }
+00217
+<a name="l00218"></a><a class="code" href="classRtMidi.html#a5">00218</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classRtMidi.html#a5">RtMidi :: getPortCount</a>( PortType type )
+00219 {
+00220 <span class="keywordflow">if</span> ( type == MIDI_INPUT )
+00221 <span class="keywordflow">return</span> MIDIGetNumberOfSources();
+00222 <span class="keywordflow">else</span> <span class="comment">// MIDI_OUTPUT</span>
+00223 <span class="keywordflow">return</span> MIDIGetNumberOfDestinations();
+00224 }
+00225
+<a name="l00226"></a><a class="code" href="classRtMidi.html#a6">00226</a> std::string <a class="code" href="classRtMidi.html#a6">RtMidi :: getPortName</a>( PortType type, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> portNumber )
+00227 {
+00228 CFStringRef nameRef;
+00229 MIDIEndpointRef portRef;
+00230 std::ostringstream ost;
+00231 <span class="keywordtype">char</span> name[128];
+00232 <span class="keywordflow">if</span> ( type == MIDI_INPUT ) {
+00233 <span class="keywordflow">if</span> ( portNumber < 0 || portNumber >= MIDIGetNumberOfSources() ) {
+00234 ost << <span class="stringliteral">"RtMidi::getPortName: the 'portNumber' argument ("</span> << portNumber << <span class="stringliteral">") is invalid."</span>;
+00235 errorString_ = ost.str();
+00236 error( RtError::INVALID_PARAMETER );
+00237 }
+00238 portRef = MIDIGetSource( portNumber );
+00239 }
+00240 <span class="keywordflow">else</span> { <span class="comment">// MIDI_OUTPUT</span>
+00241 <span class="keywordflow">if</span> ( portNumber < 0 || portNumber >= MIDIGetNumberOfDestinations() ) {
+00242 ost << <span class="stringliteral">"RtMidi::getPortName: the 'portNumber' argument ("</span> << portNumber << <span class="stringliteral">") is invalid."</span>;
+00243 errorString_ = ost.str();
+00244 error( RtError::INVALID_PARAMETER );
+00245 }
+00246 portRef = MIDIGetDestination( portNumber );
+00247 }
+00248
+00249 MIDIObjectGetStringProperty( portRef, kMIDIPropertyName, &nameRef );
+00250 CFStringGetCString( nameRef, name, <span class="keyword">sizeof</span>(name), 0);
+00251 CFRelease( nameRef );
+00252 std::string stringName = name;
+00253 <span class="keywordflow">return</span> stringName;
+00254 }
+00255
+<a name="l00256"></a><a class="code" href="classRtMidi.html#a7">00256</a> <span class="keywordtype">void</span> <a class="code" href="classRtMidi.html#a7">RtMidi :: setInputCallback</a>( RtMidiCallback callback, <span class="keywordtype">void</span> *userData)
+00257 {
+00258 callbackInfo_.userCallback = (<span class="keywordtype">void</span> *) callback;
+00259 callbackInfo_.userData = userData;
+00260 callbackInfo_.usingCallback = <span class="keyword">true</span>;
+00261 }
+00262
+00263 <span class="keyword">const</span> RtMidi::MidiMessage* <a class="code" href="classRtMidi.html#a10">RtMidi :: getMessage</a>( <span class="keywordtype">void</span> )
+00264 {
+00265 currentMessage_.bytes.clear();
+00266 <span class="keywordflow">if</span> ( !connected_ ) {
+00267 errorString_ = <span class="stringliteral">"RtMidi::getNextMessage: a port is not open!"</span>;
+00268 error( RtError::WARNING );
+00269 <span class="keywordflow">return</span> &currentMessage_;
+00270 }
+00271
+00272 <span class="keywordflow">if</span> ( !isInputPort_ ) {
+00273 errorString_ = <span class="stringliteral">"RtMidi::getNextMessage: this is not an input port!"</span>;
+00274 error( RtError::WARNING );
+00275 <span class="keywordflow">return</span> &currentMessage_;
+00276 }
+00277
+00278 <span class="keywordflow">if</span> ( callbackInfo_.usingCallback ) {
+00279 errorString_ = <span class="stringliteral">"RtMidi::getNextMessage: a user callback is currently set for this port."</span>;
+00280 error( RtError::WARNING );
+00281 <span class="keywordflow">return</span> &currentMessage_;
+00282 }
+00283
+00284 <span class="keywordflow">if</span> ( readIndex_ == callbackInfo_.writeIndex ) <span class="keywordflow">return</span> &currentMessage_;
+00285
+00286 currentMessage_ = callbackInfo_.buffer[readIndex_++];
+00287 <span class="keywordflow">if</span> ( readIndex_ >= nMessages ) readIndex_ = 0;
+00288
+00289 <span class="keywordflow">return</span> &currentMessage_;
+00290 }
+00291
+00292 <span class="keywordtype">bool</span> <a class="code" href="classRtMidi.html#a11">RtMidi :: sendMessage</a>( <span class="keyword">const</span> MidiMessage *message )
+00293 {
+00294 <span class="keywordflow">if</span> ( !connected_ ) {
+00295 errorString_ = <span class="stringliteral">"RtMidi::sendMessage: a port is not open!"</span>;
+00296 error( RtError::WARNING );
+00297 <span class="keywordflow">return</span> <span class="keyword">false</span>;
+00298 }
+00299
+00300 <span class="keywordflow">if</span> ( isInputPort_ ) {
+00301 errorString_ = <span class="stringliteral">"RtMidi::sendMessage: this is not an output port!"</span>;
+00302 error( RtError::WARNING );
+00303 <span class="keywordflow">return</span> <span class="keyword">false</span>;
+00304 }
+00305
+00306 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nBytes = message->bytes.size();
+00307 <span class="comment">// Pad the buffer for extra (unknown) structure data.</span>
+00308 Byte buffer[nBytes+32];
+00309 MIDIPacketList *pktlist = (MIDIPacketList *) buffer;
+00310 MIDIPacket *curPacket = MIDIPacketListInit( pktlist );
+00311
+00312 MIDITimeStamp timeStamp = 0;
+00313 <span class="comment">// If a non-zero delta or absolute time, convert to CoreMIDI's host time.</span>
+00314 <span class="keywordflow">if</span> ( message->timeStamp != 0.0 ) {
+00315 <span class="keywordflow">if</span> ( callbackInfo_.doDeltaTime ) {
+00316 timeStamp = AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() );
+00317 timeStamp += (UInt64) (message->timeStamp * 1000000000.0);
+00318 timeStamp = AudioConvertNanosToHostTime( timeStamp );
+00319 }
+00320 <span class="keywordflow">else</span> {
+00321 timeval tvTime;
+00322 <span class="keywordtype">double</span> time;
+00323 <span class="keywordflow">if</span> ( gettimeofday( &tvTime, NULL ) != 0 ) {
+00324 errorString_ = <span class="stringliteral">"RtMidi::sendMessage: error calculating time stamp."</span>;
+00325 error( RtError::WARNING );
+00326 }
+00327 <span class="keywordflow">else</span> {
+00328 time = (double) tvTime.tv_sec;
+00329 time += (double) (tvTime.tv_usec * 0.000001);
+00330 time = message->timeStamp - time;
+00331 <span class="keywordflow">if</span> ( time > 0.0 ) {
+00332 timeStamp = AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() );
+00333 timeStamp += (UInt64) (time * 1000000000.0);
+00334 timeStamp = AudioConvertNanosToHostTime( timeStamp );
+00335 }
+00336 }
+00337 }
+00338 }
+00339 curPacket = MIDIPacketListAdd( pktlist, <span class="keyword">sizeof</span>(buffer), curPacket, timeStamp, nBytes, &message->bytes[0]);
+00340
+00341 OSStatus result = MIDISend( port_, destinationId_, pktlist );
+00342 <span class="keywordflow">if</span> ( result != noErr ) {
+00343 errorString_ = <span class="stringliteral">"RtMidi::sendMessage: error sending MIDI message."</span>;
+00344 error( RtError::WARNING );
+00345 <span class="keywordflow">return</span> <span class="keyword">false</span>;
+00346 }
+00347
+00348 <span class="keywordflow">return</span> <span class="keyword">true</span>;
+00349 }
+00350
+00351 <span class="keywordtype">void</span> RtMidi :: error( RtError::Type type )
+00352 {
+00353 <span class="keywordflow">if</span> (type == RtError::WARNING) {
+00354 std::cerr << <span class="charliteral">'\n'</span> << errorString_ << <span class="stringliteral">"\n\n"</span>;
+00355 }
+00356 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (type == RtError::DEBUG_WARNING) {
+00357 <span class="preprocessor">#if defined(__RTMIDI_DEBUG__)</span>
+00358 <span class="preprocessor"></span> std::cerr << <span class="charliteral">'\n'</span> << errorString_ << <span class="stringliteral">"\n\n"</span>;
+00359 <span class="preprocessor">#endif</span>
+00360 <span class="preprocessor"></span> }
+00361 <span class="keywordflow">else</span> {
+00362 std::cerr << <span class="charliteral">'\n'</span> << errorString_ << <span class="stringliteral">"\n\n"</span>;
+00363 <span class="keywordflow">throw</span> <a class="code" href="classRtError.html">RtError</a>( errorString_, type );
+00364 }
+00365 }
+</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>©1995-2002 Perry R. Cook and Gary P. Scavone. All Rights Reserved.</td></tr>
+</table>
+
+</BODY>
+</HTML>
|
