Tutorial   Class/Enum List   File List   Compound Members   C interface  

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 /**********************************************************************/
234 /**********************************************************************/
235 
236 // **************************************************************** //
237 //
238 // RtMidiIn and RtMidiOut class declarations.
239 //
240 // RtMidiIn / RtMidiOut are "controllers" used to select an available
241 // MIDI input or output interface. They present common APIs for the
242 // user to call but all functionality is implemented by the classes
243 // MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut
244 // each create an instance of a MidiInApi or MidiOutApi subclass based
245 // on the user's API choice. If no choice is made, they attempt to
246 // make a "logical" API selection.
247 //
248 // **************************************************************** //
249 
250 class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
251 {
252  public:
253 
255  typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData );
256 
258 
275  RtMidiIn( RtMidi::Api api=UNSPECIFIED,
276  const std::string& clientName = "RtMidi Input Client",
277  unsigned int queueSizeLimit = 100 );
278 
280  ~RtMidiIn ( void ) throw();
281 
283  RtMidi::Api getCurrentApi( void ) throw();
284 
286 
291  void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Input" ) );
292 
294 
303  void openVirtualPort( const std::string &portName = std::string( "RtMidi Input" ) );
304 
306 
316  void setCallback( RtMidiCallback callback, void *userData = 0 );
317 
319 
323  void cancelCallback();
324 
326  void closePort( void );
327 
329 
333  virtual bool isPortOpen() const;
334 
336 
339  unsigned int getPortCount();
340 
342 
347  std::string getPortName( unsigned int portNumber = 0 );
348 
350 
357  void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
358 
360 
367  double getMessage( std::vector<unsigned char> *message );
368 
370 
374  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
375 
376  protected:
377  void openMidiApi( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit );
378 };
379 
380 /**********************************************************************/
394 /**********************************************************************/
395 
396 class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi
397 {
398  public:
400 
407  RtMidiOut( RtMidi::Api api=UNSPECIFIED,
408  const std::string& clientName = "RtMidi Output Client" );
409 
411  ~RtMidiOut( void ) throw();
412 
414  RtMidi::Api getCurrentApi( void ) throw();
415 
417 
423  void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Output" ) );
424 
426  void closePort( void );
427 
429 
433  virtual bool isPortOpen() const;
434 
436 
444  void openVirtualPort( const std::string &portName = std::string( "RtMidi Output" ) );
445 
447  unsigned int getPortCount( void );
448 
450 
455  std::string getPortName( unsigned int portNumber = 0 );
456 
458 
462  void sendMessage( const std::vector<unsigned char> *message );
463 
465 
472  void sendMessage( const unsigned char *message, size_t size );
473 
475 
479  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
480 
481  protected:
482  void openMidiApi( RtMidi::Api api, const std::string &clientName );
483 };
484 
485 
486 // **************************************************************** //
487 //
488 // MidiInApi / MidiOutApi class declarations.
489 //
490 // Subclasses of MidiInApi and MidiOutApi contain all API- and
491 // OS-specific code necessary to fully implement the RtMidi API.
492 //
493 // Note that MidiInApi and MidiOutApi are abstract base classes and
494 // cannot be explicitly instantiated. RtMidiIn and RtMidiOut will
495 // create instances of a MidiInApi or MidiOutApi subclass.
496 //
497 // **************************************************************** //
498 
499 class RTMIDI_DLL_PUBLIC MidiApi
500 {
501  public:
502 
503  MidiApi();
504  virtual ~MidiApi();
505  virtual RtMidi::Api getCurrentApi( void ) = 0;
506  virtual void openPort( unsigned int portNumber, const std::string &portName ) = 0;
507  virtual void openVirtualPort( const std::string &portName ) = 0;
508  virtual void closePort( void ) = 0;
509  virtual void setClientName( const std::string &clientName ) = 0;
510  virtual void setPortName( const std::string &portName ) = 0;
511 
512  virtual unsigned int getPortCount( void ) = 0;
513  virtual std::string getPortName( unsigned int portNumber ) = 0;
514 
515  inline bool isPortOpen() const { return connected_; }
516  void setErrorCallback( RtMidiErrorCallback errorCallback, void *userData );
517 
519  void error( RtMidiError::Type type, std::string errorString );
520 
521 protected:
522  virtual void initialize( const std::string& clientName ) = 0;
523 
524  void *apiData_;
525  bool connected_;
526  std::string errorString_;
527  RtMidiErrorCallback errorCallback_;
528  bool firstErrorOccurred_;
529  void *errorCallbackUserData_;
530 };
531 
532 class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
533 {
534  public:
535 
536  MidiInApi( unsigned int queueSizeLimit );
537  virtual ~MidiInApi( void );
538  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
539  void cancelCallback( void );
540  virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
541  double getMessage( std::vector<unsigned char> *message );
542 
543  // A MIDI structure used internally by the class to store incoming
544  // messages. Each message represents one and only one MIDI message.
545  struct MidiMessage {
546  std::vector<unsigned char> bytes;
547 
549  double timeStamp;
550 
551  // Default constructor.
552  MidiMessage()
553  : bytes(0), timeStamp(0.0) {}
554  };
555 
556  struct MidiQueue {
557  unsigned int front;
558  unsigned int back;
559  unsigned int ringSize;
560  MidiMessage *ring;
561 
562  // Default constructor.
563  MidiQueue()
564  : front(0), back(0), ringSize(0), ring(0) {}
565  bool push( const MidiMessage& );
566  bool pop( std::vector<unsigned char>*, double* );
567  unsigned int size( unsigned int *back=0, unsigned int *front=0 );
568  };
569 
570  // The RtMidiInData structure is used to pass private class data to
571  // the MIDI input handling function or thread.
572  struct RtMidiInData {
573  MidiQueue queue;
574  MidiMessage message;
575  unsigned char ignoreFlags;
576  bool doInput;
577  bool firstMessage;
578  void *apiData;
579  bool usingCallback;
580  RtMidiIn::RtMidiCallback userCallback;
581  void *userData;
582  bool continueSysex;
583 
584  // Default constructor.
585  RtMidiInData()
586  : ignoreFlags(7), doInput(false), firstMessage(true), apiData(0), usingCallback(false),
587  userCallback(0), userData(0), continueSysex(false) {}
588  };
589 
590  protected:
591  RtMidiInData inputData_;
592 };
593 
594 class RTMIDI_DLL_PUBLIC MidiOutApi : public MidiApi
595 {
596  public:
597 
598  MidiOutApi( void );
599  virtual ~MidiOutApi( void );
600  virtual void sendMessage( const unsigned char *message, size_t size ) = 0;
601 };
602 
603 // **************************************************************** //
604 //
605 // Inline RtMidiIn and RtMidiOut definitions.
606 //
607 // **************************************************************** //
608 
609 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
610 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); }
611 inline void RtMidiIn :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
612 inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
613 inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
614 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { static_cast<MidiInApi *>(rtapi_)->setCallback( callback, userData ); }
615 inline void RtMidiIn :: cancelCallback( void ) { static_cast<MidiInApi *>(rtapi_)->cancelCallback(); }
616 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
617 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
618 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { static_cast<MidiInApi *>(rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
619 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return static_cast<MidiInApi *>(rtapi_)->getMessage( message ); }
620 inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
621 
622 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
623 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); }
624 inline void RtMidiOut :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
625 inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
626 inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
627 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
628 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
629 inline void RtMidiOut :: sendMessage( const std::vector<unsigned char> *message ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( &message->at(0), message->size() ); }
630 inline void RtMidiOut :: sendMessage( const unsigned char *message, size_t size ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( message, size ); }
631 inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
632 
633 #endif
RtMidiError::what
virtual const char * what(void) const
Returns the thrown error message as a c-style string.
Definition: RtMidi.h:113
RtMidiIn::setCallback
void setCallback(RtMidiCallback callback, void *userData=0)
Set a callback function to be invoked for incoming MIDI messages.
Definition: RtMidi.h:614
RtMidiOut::isPortOpen
virtual bool isPortOpen() const
Returns true if a port is open and false if not.
Definition: RtMidi.h:626
RtMidi
An abstract base class for realtime MIDI input/output.
Definition: RtMidi.h:132
MidiInApi::RtMidiInData
Definition: RtMidi.h:572
RtMidi::getPortName
virtual std::string getPortName(unsigned int portNumber=0)=0
Pure virtual getPortName() function.
RtMidiOut::openVirtualPort
void openVirtualPort(const std::string &portName=std::string("RtMidi Output"))
Create a virtual output port, with optional name, to allow software connections (OS X,...
Definition: RtMidi.h:624
RtMidiIn::RtMidiCallback
void(* RtMidiCallback)(double timeStamp, std::vector< unsigned char > *message, void *userData)
User callback function type definition.
Definition: RtMidi.h:255
RtMidiOut::getPortCount
unsigned int getPortCount(void)
Return the number of available MIDI output ports.
Definition: RtMidi.h:627
MidiApi
Definition: RtMidi.h:499
RtMidiIn::getPortName
std::string getPortName(unsigned int portNumber=0)
Return a string identifier for the specified MIDI input port number.
Definition: RtMidi.h:617
MidiInApi
Definition: RtMidi.h:532
RtMidiError::DRIVER_ERROR
Definition: RtMidi.h:91
RtMidi::openPort
virtual void openPort(unsigned int portNumber=0, const std::string &portName=std::string("RtMidi"))=0
Pure virtual openPort() function.
RtMidiIn::getPortCount
unsigned int getPortCount()
Return the number of available MIDI input ports.
Definition: RtMidi.h:616
RtMidiIn::ignoreTypes
void ignoreTypes(bool midiSysex=true, bool midiTime=true, bool midiSense=true)
Specify whether certain MIDI message types should be queued or ignored during input.
Definition: RtMidi.h:618
RtMidi::isPortOpen
virtual bool isPortOpen(void) const =0
Returns true if a port is open and false if not.
RtMidi::WINDOWS_MM
Definition: RtMidi.h:141
RtMidiError::SYSTEM_ERROR
Definition: RtMidi.h:92
RtMidiIn::getMessage
double getMessage(std::vector< unsigned char > *message)
Fill the user-provided vector with the data bytes for the next available MIDI message in the input qu...
Definition: RtMidi.h:619
RtMidiOut::openPort
void openPort(unsigned int portNumber=0, const std::string &portName=std::string("RtMidi Output"))
Open a MIDI output connection.
Definition: RtMidi.h:623
MidiOutApi
Definition: RtMidi.h:594
RtMidiError::RtMidiError
RtMidiError(const std::string &message, Type type=RtMidiError::UNSPECIFIED)
The constructor.
Definition: RtMidi.h:97
RtMidiIn::closePort
void closePort(void)
Close an open MIDI connection (if one exists).
Definition: RtMidi.h:612
RtMidiError::INVALID_USE
Definition: RtMidi.h:90
RtMidiError::Type
Type
Defined RtMidiError types.
Definition: RtMidi.h:82
RtMidiOut::setErrorCallback
virtual void setErrorCallback(RtMidiErrorCallback errorCallback=NULL, void *userData=0)
Set an error callback function to be invoked when an error has occured.
Definition: RtMidi.h:631
RtMidiError::DEBUG_WARNING
Definition: RtMidi.h:84
RtMidiIn::openPort
void openPort(unsigned int portNumber=0, const std::string &portName=std::string("RtMidi Input"))
Open a MIDI input connection given by enumeration number.
Definition: RtMidi.h:610
RtMidi::setErrorCallback
virtual void setErrorCallback(RtMidiErrorCallback errorCallback=NULL, void *userData=0)=0
Set an error callback function to be invoked when an error has occured.
RtMidiError::getMessage
virtual const std::string & getMessage(void) const
Returns the thrown error message string.
Definition: RtMidi.h:110
RtMidiIn::cancelCallback
void cancelCallback()
Cancel use of the current callback function (if one exists).
Definition: RtMidi.h:615
RtMidiOut::getCurrentApi
RtMidi::Api getCurrentApi(void)
Returns the MIDI API specifier for the current instance of RtMidiOut.
Definition: RtMidi.h:622
MidiInApi::MidiQueue
Definition: RtMidi.h:556
RtMidi::closePort
virtual void closePort(void)=0
Pure virtual closePort() function.
RtMidiIn::openVirtualPort
void openVirtualPort(const std::string &portName=std::string("RtMidi Input"))
Create a virtual input port, with optional name, to allow software connections (OS X,...
Definition: RtMidi.h:611
MidiInApi::MidiMessage
Definition: RtMidi.h:545
RtMidiError
Exception handling class for RtMidi.
Definition: RtMidi.h:78
RtMidiErrorCallback
void(* RtMidiErrorCallback)(RtMidiError::Type type, const std::string &errorText, void *userData)
RtMidi error callback function prototype.
Definition: RtMidi.h:128
RtMidi::MACOSX_CORE
Definition: RtMidi.h:138
RtMidiIn::setErrorCallback
virtual void setErrorCallback(RtMidiErrorCallback errorCallback=NULL, void *userData=0)
Set an error callback function to be invoked when an error has occured.
Definition: RtMidi.h:620
RtMidiIn::isPortOpen
virtual bool isPortOpen() const
Returns true if a port is open and false if not.
Definition: RtMidi.h:613
RtMidiError::~RtMidiError
virtual ~RtMidiError(void)
The destructor.
Definition: RtMidi.h:101
RtMidiIn
A realtime MIDI input class.
Definition: RtMidi.h:250
MidiInApi::MidiMessage::timeStamp
double timeStamp
Time in seconds elapsed since the previous message.
Definition: RtMidi.h:549
RtMidiOut::getPortName
std::string getPortName(unsigned int portNumber=0)
Return a string identifier for the specified MIDI port type and number.
Definition: RtMidi.h:628
RtMidiIn::getCurrentApi
RtMidi::Api getCurrentApi(void)
Returns the MIDI API specifier for the current instance of RtMidiIn.
Definition: RtMidi.h:609
RtMidi::UNIX_JACK
Definition: RtMidi.h:140
RtMidiError::INVALID_DEVICE
Definition: RtMidi.h:87
RtMidi::openVirtualPort
virtual void openVirtualPort(const std::string &portName=std::string("RtMidi"))=0
Pure virtual openVirtualPort() function.
RtMidiError::getType
virtual const Type & getType(void) const
Returns the thrown error message type.
Definition: RtMidi.h:107
RtMidiError::printMessage
virtual void printMessage(void) const
Prints thrown error message to stderr.
Definition: RtMidi.h:104
RtMidi::RTMIDI_DUMMY
Definition: RtMidi.h:142
RtMidi::Api
Api
MIDI API specifier arguments.
Definition: RtMidi.h:136
RtMidi::UNSPECIFIED
Definition: RtMidi.h:137
RtMidiOut::closePort
void closePort(void)
Close an open MIDI connection (if one exists).
Definition: RtMidi.h:625
RtMidiError::WARNING
Definition: RtMidi.h:83
RtMidiError::INVALID_PARAMETER
Definition: RtMidi.h:89
RtMidiError::NO_DEVICES_FOUND
Definition: RtMidi.h:86
RtMidiOut
A realtime MIDI output class.
Definition: RtMidi.h:396
RtMidiError::MEMORY_ERROR
Definition: RtMidi.h:88
RtMidi::getPortCount
virtual unsigned int getPortCount()=0
Pure virtual getPortCount() function.
RtMidiError::UNSPECIFIED
Definition: RtMidi.h:85
RtMidi::LINUX_ALSA
Definition: RtMidi.h:139
RtMidiOut::sendMessage
void sendMessage(const std::vector< unsigned char > *message)
Immediately send a single message out an open MIDI output port.
Definition: RtMidi.h:629

©2003-2019 Gary P. Scavone, McGill University. All Rights Reserved.
Maintained by Gary P. Scavone, gary at music.mcgill.ca