Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

# 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

The Synthesis ToolKit in C++ (STK)
©1995-2012 Perry R. Cook and Gary P. Scavone. All Rights Reserved.