Tutorial   Class/Enum List   File List   Compound Members  

RtMidi.h

Go to the documentation of this file.
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