Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


RtMidi.h
Go to the documentation of this file.
1 /**********************************************************************/
38 /**********************************************************************/
39 
44 #ifndef RTMIDI_H
45 #define RTMIDI_H
46 
47 #if defined _WIN32 || defined __CYGWIN__
48  #if defined(RTMIDI_EXPORT)
49  #define RTMIDI_DLL_PUBLIC __declspec(dllexport)
50  #else
51  #define RTMIDI_DLL_PUBLIC
52  #endif
53 #else
54  #if __GNUC__ >= 4
55  #define RTMIDI_DLL_PUBLIC __attribute__( (visibility( "default" )) )
56  #else
57  #define RTMIDI_DLL_PUBLIC
58  #endif
59 #endif
60 
61 #define RTMIDI_VERSION "4.0.0"
62 
63 #include <exception>
64 #include <iostream>
65 #include <string>
66 #include <vector>
67 
68 /************************************************************************/
76 /************************************************************************/
77 
78 class RTMIDI_DLL_PUBLIC RtMidiError : public std::exception
79 {
80  public:
82  enum Type {
93  THREAD_ERROR
94  };
95 
97  RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw()
98  : message_(message), type_(type) {}
99 
101  virtual ~RtMidiError( void ) throw() {}
102 
104  virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
105 
107  virtual const Type& getType( void ) const throw() { return type_; }
108 
110  virtual const std::string& getMessage( void ) const throw() { return message_; }
111 
113  virtual const char* what( void ) const throw() { return message_.c_str(); }
114 
115  protected:
116  std::string message_;
117  Type type_;
118 };
119 
121 
128 typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData );
129 
130 class MidiApi;
131 
132 class RTMIDI_DLL_PUBLIC RtMidi
133 {
134  public:
136  enum Api {
143  NUM_APIS
144  };
145 
147  static std::string getVersion( void ) throw();
148 
150 
155  static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
156 
158 
163  static std::string getApiName( RtMidi::Api api );
164 
166 
170  static std::string getApiDisplayName( RtMidi::Api api );
171 
173 
178  static RtMidi::Api getCompiledApiByName( const std::string &name );
179 
181  virtual void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi" ) ) = 0;
182 
184  virtual void openVirtualPort( const std::string &portName = std::string( "RtMidi" ) ) = 0;
185 
187  virtual unsigned int getPortCount() = 0;
188 
190  virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
191 
193  virtual void closePort( void ) = 0;
194 
195  void setClientName( const std::string &clientName );
196  void setPortName( const std::string &portName );
197 
199 
203  virtual bool isPortOpen( void ) const = 0;
204 
206 
210  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0;
211 
212  protected:
213  RtMidi();
214  virtual ~RtMidi();
215  MidiApi *rtapi_;
216 };
217 
218 /**********************************************************************/
232 /**********************************************************************/
233 
234 // **************************************************************** //
235 //
236 // RtMidiIn and RtMidiOut class declarations.
237 //
238 // RtMidiIn / RtMidiOut are "controllers" used to select an available
239 // MIDI input or output interface. They present common APIs for the
240 // user to call but all functionality is implemented by the classes
241 // MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut
242 // each create an instance of a MidiInApi or MidiOutApi subclass based
243 // on the user's API choice. If no choice is made, they attempt to
244 // make a "logical" API selection.
245 //
246 // **************************************************************** //
247 
248 class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
249 {
250  public:
251 
253  typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData );
254 
256 
273  RtMidiIn( RtMidi::Api api=UNSPECIFIED,
274  const std::string& clientName = "RtMidi Input Client",
275  unsigned int queueSizeLimit = 100 );
276 
278  ~RtMidiIn ( void ) throw();
279 
281  RtMidi::Api getCurrentApi( void ) throw();
282 
284 
289  void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Input" ) );
290 
292 
301  void openVirtualPort( const std::string &portName = std::string( "RtMidi Input" ) );
302 
304 
314  void setCallback( RtMidiCallback callback, void *userData = 0 );
315 
317 
321  void cancelCallback();
322 
324  void closePort( void );
325 
327 
331  virtual bool isPortOpen() const;
332 
334 
337  unsigned int getPortCount();
338 
340 
345  std::string getPortName( unsigned int portNumber = 0 );
346 
348 
355  void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
356 
358 
365  double getMessage( std::vector<unsigned char> *message );
366 
368 
372  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
373 
374  protected:
375  void openMidiApi( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit );
376 };
377 
378 /**********************************************************************/
390 /**********************************************************************/
391 
392 class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi
393 {
394  public:
396 
403  RtMidiOut( RtMidi::Api api=UNSPECIFIED,
404  const std::string& clientName = "RtMidi Output Client" );
405 
407  ~RtMidiOut( void ) throw();
408 
410  RtMidi::Api getCurrentApi( void ) throw();
411 
413 
419  void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Output" ) );
420 
422  void closePort( void );
423 
425 
429  virtual bool isPortOpen() const;
430 
432 
440  void openVirtualPort( const std::string &portName = std::string( "RtMidi Output" ) );
441 
443  unsigned int getPortCount( void );
444 
446 
451  std::string getPortName( unsigned int portNumber = 0 );
452 
454 
458  void sendMessage( const std::vector<unsigned char> *message );
459 
461 
468  void sendMessage( const unsigned char *message, size_t size );
469 
471 
475  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
476 
477  protected:
478  void openMidiApi( RtMidi::Api api, const std::string &clientName );
479 };
480 
481 
482 // **************************************************************** //
483 //
484 // MidiInApi / MidiOutApi class declarations.
485 //
486 // Subclasses of MidiInApi and MidiOutApi contain all API- and
487 // OS-specific code necessary to fully implement the RtMidi API.
488 //
489 // Note that MidiInApi and MidiOutApi are abstract base classes and
490 // cannot be explicitly instantiated. RtMidiIn and RtMidiOut will
491 // create instances of a MidiInApi or MidiOutApi subclass.
492 //
493 // **************************************************************** //
494 
495 class RTMIDI_DLL_PUBLIC MidiApi
496 {
497  public:
498 
499  MidiApi();
500  virtual ~MidiApi();
501  virtual RtMidi::Api getCurrentApi( void ) = 0;
502  virtual void openPort( unsigned int portNumber, const std::string &portName ) = 0;
503  virtual void openVirtualPort( const std::string &portName ) = 0;
504  virtual void closePort( void ) = 0;
505  virtual void setClientName( const std::string &clientName ) = 0;
506  virtual void setPortName( const std::string &portName ) = 0;
507 
508  virtual unsigned int getPortCount( void ) = 0;
509  virtual std::string getPortName( unsigned int portNumber ) = 0;
510 
511  inline bool isPortOpen() const { return connected_; }
512  void setErrorCallback( RtMidiErrorCallback errorCallback, void *userData );
513 
515  void error( RtMidiError::Type type, std::string errorString );
516 
517 protected:
518  virtual void initialize( const std::string& clientName ) = 0;
519 
520  void *apiData_;
521  bool connected_;
522  std::string errorString_;
523  RtMidiErrorCallback errorCallback_;
524  bool firstErrorOccurred_;
525  void *errorCallbackUserData_;
526 };
527 
528 class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
529 {
530  public:
531 
532  MidiInApi( unsigned int queueSizeLimit );
533  virtual ~MidiInApi( void );
534  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
535  void cancelCallback( void );
536  virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
537  double getMessage( std::vector<unsigned char> *message );
538 
539  // A MIDI structure used internally by the class to store incoming
540  // messages. Each message represents one and only one MIDI message.
541  struct MidiMessage {
542  std::vector<unsigned char> bytes;
543 
545  double timeStamp;
546 
547  // Default constructor.
548  MidiMessage()
549  : bytes(0), timeStamp(0.0) {}
550  };
551 
552  struct MidiQueue {
553  unsigned int front;
554  unsigned int back;
555  unsigned int ringSize;
556  MidiMessage *ring;
557 
558  // Default constructor.
559  MidiQueue()
560  : front(0), back(0), ringSize(0), ring(0) {}
561  bool push( const MidiMessage& );
562  bool pop( std::vector<unsigned char>*, double* );
563  unsigned int size( unsigned int *back=0, unsigned int *front=0 );
564  };
565 
566  // The RtMidiInData structure is used to pass private class data to
567  // the MIDI input handling function or thread.
568  struct RtMidiInData {
569  MidiQueue queue;
570  MidiMessage message;
571  unsigned char ignoreFlags;
572  bool doInput;
573  bool firstMessage;
574  void *apiData;
575  bool usingCallback;
576  RtMidiIn::RtMidiCallback userCallback;
577  void *userData;
578  bool continueSysex;
579 
580  // Default constructor.
581  RtMidiInData()
582  : ignoreFlags(7), doInput(false), firstMessage(true), apiData(0), usingCallback(false),
583  userCallback(0), userData(0), continueSysex(false) {}
584  };
585 
586  protected:
587  RtMidiInData inputData_;
588 };
589 
590 class RTMIDI_DLL_PUBLIC MidiOutApi : public MidiApi
591 {
592  public:
593 
594  MidiOutApi( void );
595  virtual ~MidiOutApi( void );
596  virtual void sendMessage( const unsigned char *message, size_t size ) = 0;
597 };
598 
599 // **************************************************************** //
600 //
601 // Inline RtMidiIn and RtMidiOut definitions.
602 //
603 // **************************************************************** //
604 
605 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
606 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); }
607 inline void RtMidiIn :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
608 inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
609 inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
610 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { static_cast<MidiInApi *>(rtapi_)->setCallback( callback, userData ); }
611 inline void RtMidiIn :: cancelCallback( void ) { static_cast<MidiInApi *>(rtapi_)->cancelCallback(); }
612 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
613 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
614 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { static_cast<MidiInApi *>(rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
615 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return static_cast<MidiInApi *>(rtapi_)->getMessage( message ); }
616 inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
617 
618 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
619 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); }
620 inline void RtMidiOut :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
621 inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
622 inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
623 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
624 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
625 inline void RtMidiOut :: sendMessage( const std::vector<unsigned char> *message ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( &message->at(0), message->size() ); }
626 inline void RtMidiOut :: sendMessage( const unsigned char *message, size_t size ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( message, size ); }
627 inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
628 
629 #endif

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