00001 /**********************************************************************/ 00037 /**********************************************************************/ 00038 00043 // RtMidi: Version 2.0.1 00044 00045 #ifndef RTMIDI_H 00046 #define RTMIDI_H 00047 00048 #include "RtError.h" 00049 #include <string> 00050 #include <vector> 00051 00052 class RtMidi 00053 { 00054 public: 00055 00057 enum Api { 00058 UNSPECIFIED, 00059 MACOSX_CORE, 00060 LINUX_ALSA, 00061 UNIX_JACK, 00062 WINDOWS_MM, 00063 WINDOWS_KS, 00064 RTMIDI_DUMMY 00065 }; 00066 00068 00073 static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw(); 00074 00076 virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; 00077 00079 virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; 00080 00082 virtual unsigned int getPortCount() = 0; 00083 00085 virtual std::string getPortName( unsigned int portNumber = 0 ) = 0; 00086 00088 virtual void closePort( void ) = 0; 00089 00091 static void error( RtError::Type type, std::string errorString ); 00092 00093 protected: 00094 00095 RtMidi() {}; 00096 virtual ~RtMidi() {}; 00097 }; 00098 00099 /**********************************************************************/ 00115 /**********************************************************************/ 00116 00117 // **************************************************************** // 00118 // 00119 // RtMidiIn and RtMidiOut class declarations. 00120 // 00121 // RtMidiIn / RtMidiOut are "controllers" used to select an available 00122 // MIDI input or output interface. They present common APIs for the 00123 // user to call but all functionality is implemented by the classes 00124 // MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut 00125 // each create an instance of a MidiInApi or MidiOutApi subclass based 00126 // on the user's API choice. If no choice is made, they attempt to 00127 // make a "logical" API selection. 00128 // 00129 // **************************************************************** // 00130 00131 class MidiInApi; 00132 class MidiOutApi; 00133 00134 class RtMidiIn : public RtMidi 00135 { 00136 public: 00137 00139 typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData); 00140 00142 00153 RtMidiIn( RtMidi::Api api=UNSPECIFIED, 00154 const std::string clientName = std::string( "RtMidi Input Client"), 00155 unsigned int queueSizeLimit = 100 ); 00156 00158 ~RtMidiIn ( void ) throw(); 00159 00161 RtMidi::Api getCurrentApi( void ) throw(); 00162 00164 00168 void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) ); 00169 00171 00177 void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) ); 00178 00180 00186 void setCallback( RtMidiCallback callback, void *userData = 0 ); 00187 00189 00193 void cancelCallback(); 00194 00196 void closePort( void ); 00197 00199 unsigned int getPortCount(); 00200 00202 00205 std::string getPortName( unsigned int portNumber = 0 ); 00206 00208 00215 void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true ); 00216 00218 00225 double getMessage( std::vector<unsigned char> *message ); 00226 00227 protected: 00228 void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit ); 00229 MidiInApi *rtapi_; 00230 00231 }; 00232 00233 /**********************************************************************/ 00247 /**********************************************************************/ 00248 00249 class RtMidiOut : public RtMidi 00250 { 00251 public: 00252 00254 00261 RtMidiOut( RtMidi::Api api=UNSPECIFIED, 00262 const std::string clientName = std::string( "RtMidi Output Client") ); 00263 00265 ~RtMidiOut( void ) throw(); 00266 00268 RtMidi::Api getCurrentApi( void ) throw(); 00269 00271 00277 void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) ); 00278 00280 void closePort( void ); 00281 00283 00291 void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) ); 00292 00294 unsigned int getPortCount( void ); 00295 00297 00300 std::string getPortName( unsigned int portNumber = 0 ); 00301 00303 00307 void sendMessage( std::vector<unsigned char> *message ); 00308 00309 protected: 00310 void openMidiApi( RtMidi::Api api, const std::string clientName ); 00311 MidiOutApi *rtapi_; 00312 }; 00313 00314 00315 // **************************************************************** // 00316 // 00317 // MidiInApi / MidiOutApi class declarations. 00318 // 00319 // Subclasses of MidiInApi and MidiOutApi contain all API- and 00320 // OS-specific code necessary to fully implement the RtMidi API. 00321 // 00322 // Note that MidiInApi and MidiOutApi are abstract base classes and 00323 // cannot be explicitly instantiated. RtMidiIn and RtMidiOut will 00324 // create instances of a MidiInApi or MidiOutApi subclass. 00325 // 00326 // **************************************************************** // 00327 00328 class MidiInApi 00329 { 00330 public: 00331 00332 MidiInApi( unsigned int queueSizeLimit ); 00333 virtual ~MidiInApi( void ); 00334 virtual RtMidi::Api getCurrentApi( void ) = 0; 00335 virtual void openPort( unsigned int portNumber, const std::string portName ) = 0; 00336 virtual void openVirtualPort( const std::string portName ) = 0; 00337 virtual void closePort( void ) = 0; 00338 void setCallback( RtMidiIn::RtMidiCallback callback, void *userData ); 00339 void cancelCallback( void ); 00340 virtual unsigned int getPortCount( void ) = 0; 00341 virtual std::string getPortName( unsigned int portNumber ) = 0; 00342 virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ); 00343 double getMessage( std::vector<unsigned char> *message ); 00344 00345 // A MIDI structure used internally by the class to store incoming 00346 // messages. Each message represents one and only one MIDI message. 00347 struct MidiMessage { 00348 std::vector<unsigned char> bytes; 00349 double timeStamp; 00350 00351 // Default constructor. 00352 MidiMessage() 00353 :bytes(0), timeStamp(0.0) {} 00354 }; 00355 00356 struct MidiQueue { 00357 unsigned int front; 00358 unsigned int back; 00359 unsigned int size; 00360 unsigned int ringSize; 00361 MidiMessage *ring; 00362 00363 // Default constructor. 00364 MidiQueue() 00365 :front(0), back(0), size(0), ringSize(0) {} 00366 }; 00367 00368 // The RtMidiInData structure is used to pass private class data to 00369 // the MIDI input handling function or thread. 00370 struct RtMidiInData { 00371 MidiQueue queue; 00372 MidiMessage message; 00373 unsigned char ignoreFlags; 00374 bool doInput; 00375 bool firstMessage; 00376 void *apiData; 00377 bool usingCallback; 00378 void *userCallback; 00379 void *userData; 00380 bool continueSysex; 00381 00382 // Default constructor. 00383 RtMidiInData() 00384 : ignoreFlags(7), doInput(false), firstMessage(true), 00385 apiData(0), usingCallback(false), userCallback(0), userData(0), 00386 continueSysex(false) {} 00387 }; 00388 00389 protected: 00390 virtual void initialize( const std::string& clientName ) = 0; 00391 RtMidiInData inputData_; 00392 00393 void *apiData_; 00394 bool connected_; 00395 std::string errorString_; 00396 }; 00397 00398 class MidiOutApi 00399 { 00400 public: 00401 00402 MidiOutApi( void ); 00403 virtual ~MidiOutApi( void ); 00404 virtual RtMidi::Api getCurrentApi( void ) = 0; 00405 virtual void openPort( unsigned int portNumber, const std::string portName ) = 0; 00406 virtual void openVirtualPort( const std::string portName ) = 0; 00407 virtual void closePort( void ) = 0; 00408 virtual unsigned int getPortCount( void ) = 0; 00409 virtual std::string getPortName( unsigned int portNumber ) = 0; 00410 virtual void sendMessage( std::vector<unsigned char> *message ) = 0; 00411 00412 protected: 00413 virtual void initialize( const std::string& clientName ) = 0; 00414 00415 void *apiData_; 00416 bool connected_; 00417 std::string errorString_; 00418 }; 00419 00420 // **************************************************************** // 00421 // 00422 // Inline RtMidiIn and RtMidiOut definitions. 00423 // 00424 // **************************************************************** // 00425 00426 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } 00427 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { return rtapi_->openPort( portNumber, portName ); } 00428 inline void RtMidiIn :: openVirtualPort( const std::string portName ) { return rtapi_->openVirtualPort( portName ); } 00429 inline void RtMidiIn :: closePort( void ) { return rtapi_->closePort(); } 00430 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { return rtapi_->setCallback( callback, userData ); } 00431 inline void RtMidiIn :: cancelCallback( void ) { return rtapi_->cancelCallback(); } 00432 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); } 00433 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } 00434 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { return rtapi_->ignoreTypes( midiSysex, midiTime, midiSense ); } 00435 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return rtapi_->getMessage( message ); } 00436 00437 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } 00438 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { return rtapi_->openPort( portNumber, portName ); } 00439 inline void RtMidiOut :: openVirtualPort( const std::string portName ) { return rtapi_->openVirtualPort( portName ); } 00440 inline void RtMidiOut :: closePort( void ) { return rtapi_->closePort(); } 00441 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); } 00442 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } 00443 inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { return rtapi_->sendMessage( message ); } 00444 00445 // **************************************************************** // 00446 // 00447 // MidiInApi and MidiOutApi subclass prototypes. 00448 // 00449 // **************************************************************** // 00450 00451 #if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__) && !defined(__WINDOWS_KS__) 00452 #define __RTMIDI_DUMMY__ 00453 #endif 00454 00455 #if defined(__MACOSX_CORE__) 00456 00457 class MidiInCore: public MidiInApi 00458 { 00459 public: 00460 MidiInCore( const std::string clientName, unsigned int queueSizeLimit ); 00461 ~MidiInCore( void ); 00462 RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; 00463 void openPort( unsigned int portNumber, const std::string portName ); 00464 void openVirtualPort( const std::string portName ); 00465 void closePort( void ); 00466 unsigned int getPortCount( void ); 00467 std::string getPortName( unsigned int portNumber ); 00468 00469 protected: 00470 void initialize( const std::string& clientName ); 00471 }; 00472 00473 class MidiOutCore: public MidiOutApi 00474 { 00475 public: 00476 MidiOutCore( const std::string clientName ); 00477 ~MidiOutCore( void ); 00478 RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; 00479 void openPort( unsigned int portNumber, const std::string portName ); 00480 void openVirtualPort( const std::string portName ); 00481 void closePort( void ); 00482 unsigned int getPortCount( void ); 00483 std::string getPortName( unsigned int portNumber ); 00484 void sendMessage( std::vector<unsigned char> *message ); 00485 00486 protected: 00487 void initialize( const std::string& clientName ); 00488 }; 00489 00490 #endif 00491 00492 #if defined(__UNIX_JACK__) 00493 00494 class MidiInJack: public MidiInApi 00495 { 00496 public: 00497 MidiInJack( const std::string clientName, unsigned int queueSizeLimit ); 00498 ~MidiInJack( void ); 00499 RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; 00500 void openPort( unsigned int portNumber, const std::string portName ); 00501 void openVirtualPort( const std::string portName ); 00502 void closePort( void ); 00503 unsigned int getPortCount( void ); 00504 std::string getPortName( unsigned int portNumber ); 00505 00506 protected: 00507 void initialize( const std::string& clientName ); 00508 }; 00509 00510 class MidiOutJack: public MidiOutApi 00511 { 00512 public: 00513 MidiOutJack( const std::string clientName ); 00514 ~MidiOutJack( void ); 00515 RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; 00516 void openPort( unsigned int portNumber, const std::string portName ); 00517 void openVirtualPort( const std::string portName ); 00518 void closePort( void ); 00519 unsigned int getPortCount( void ); 00520 std::string getPortName( unsigned int portNumber ); 00521 void sendMessage( std::vector<unsigned char> *message ); 00522 00523 protected: 00524 void initialize( const std::string& clientName ); 00525 }; 00526 00527 #endif 00528 00529 #if defined(__LINUX_ALSA__) 00530 00531 class MidiInAlsa: public MidiInApi 00532 { 00533 public: 00534 MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ); 00535 ~MidiInAlsa( void ); 00536 RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; 00537 void openPort( unsigned int portNumber, const std::string portName ); 00538 void openVirtualPort( const std::string portName ); 00539 void closePort( void ); 00540 unsigned int getPortCount( void ); 00541 std::string getPortName( unsigned int portNumber ); 00542 00543 protected: 00544 void initialize( const std::string& clientName ); 00545 }; 00546 00547 class MidiOutAlsa: public MidiOutApi 00548 { 00549 public: 00550 MidiOutAlsa( const std::string clientName ); 00551 ~MidiOutAlsa( void ); 00552 RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; 00553 void openPort( unsigned int portNumber, const std::string portName ); 00554 void openVirtualPort( const std::string portName ); 00555 void closePort( void ); 00556 unsigned int getPortCount( void ); 00557 std::string getPortName( unsigned int portNumber ); 00558 void sendMessage( std::vector<unsigned char> *message ); 00559 00560 protected: 00561 void initialize( const std::string& clientName ); 00562 }; 00563 00564 #endif 00565 00566 #if defined(__WINDOWS_MM__) 00567 00568 class MidiInWinMM: public MidiInApi 00569 { 00570 public: 00571 MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ); 00572 ~MidiInWinMM( void ); 00573 RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; 00574 void openPort( unsigned int portNumber, const std::string portName ); 00575 void openVirtualPort( const std::string portName ); 00576 void closePort( void ); 00577 unsigned int getPortCount( void ); 00578 std::string getPortName( unsigned int portNumber ); 00579 00580 protected: 00581 void initialize( const std::string& clientName ); 00582 }; 00583 00584 class MidiOutWinMM: public MidiOutApi 00585 { 00586 public: 00587 MidiOutWinMM( const std::string clientName ); 00588 ~MidiOutWinMM( void ); 00589 RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; 00590 void openPort( unsigned int portNumber, const std::string portName ); 00591 void openVirtualPort( const std::string portName ); 00592 void closePort( void ); 00593 unsigned int getPortCount( void ); 00594 std::string getPortName( unsigned int portNumber ); 00595 void sendMessage( std::vector<unsigned char> *message ); 00596 00597 protected: 00598 void initialize( const std::string& clientName ); 00599 }; 00600 00601 #endif 00602 00603 #if defined(__WINDOWS_KS__) 00604 00605 class MidiInWinKS: public MidiInApi 00606 { 00607 public: 00608 MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ); 00609 ~MidiInWinKS( void ); 00610 RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; 00611 void openPort( unsigned int portNumber, const std::string portName ); 00612 void openVirtualPort( const std::string portName ); 00613 void closePort( void ); 00614 unsigned int getPortCount( void ); 00615 std::string getPortName( unsigned int portNumber ); 00616 00617 protected: 00618 void initialize( const std::string& clientName ); 00619 }; 00620 00621 class MidiOutWinKS: public MidiOutApi 00622 { 00623 public: 00624 MidiOutWinKS( const std::string clientName ); 00625 ~MidiOutWinKS( void ); 00626 RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; 00627 void openPort( unsigned int portNumber, const std::string portName ); 00628 void openVirtualPort( const std::string portName ); 00629 void closePort( void ); 00630 unsigned int getPortCount( void ); 00631 std::string getPortName( unsigned int portNumber ); 00632 void sendMessage( std::vector<unsigned char> *message ); 00633 00634 protected: 00635 void initialize( const std::string& clientName ); 00636 }; 00637 00638 #endif 00639 00640 #if defined(__RTMIDI_DUMMY__) 00641 00642 class MidiInDummy: public MidiInApi 00643 { 00644 public: 00645 MidiInDummy( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; RtMidi::error( RtError::WARNING, errorString_ ); }; 00646 RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }; 00647 void openPort( unsigned int portNumber, const std::string portName ) {}; 00648 void openVirtualPort( const std::string portName ) {}; 00649 void closePort( void ) {}; 00650 unsigned int getPortCount( void ) { return 0; }; 00651 std::string getPortName( unsigned int portNumber ) { return ""; }; 00652 00653 protected: 00654 void initialize( const std::string& clientName ) {}; 00655 }; 00656 00657 class MidiOutDummy: public MidiOutApi 00658 { 00659 public: 00660 MidiOutDummy( const std::string clientName ) { errorString_ = "MidiOutDummy: This class provides no functionality."; RtMidi::error( RtError::WARNING, errorString_ ); }; 00661 RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }; 00662 void openPort( unsigned int portNumber, const std::string portName ) {}; 00663 void openVirtualPort( const std::string portName ) {}; 00664 void closePort( void ) {}; 00665 unsigned int getPortCount( void ) { return 0; }; 00666 std::string getPortName( unsigned int portNumber ) { return ""; }; 00667 void sendMessage( std::vector<unsigned char> *message ) {}; 00668 00669 protected: 00670 void initialize( const std::string& clientName ) {}; 00671 }; 00672 00673 #endif 00674 00675 #endif
©2003-2012 Gary P. Scavone, McGill University. All Rights Reserved. Maintained by Gary P. Scavone, gary at music.mcgill.ca |