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 "5.0.0"
62 
63 #include <exception>
64 #include <iostream>
65 #include <string>
66 #include <vector>
67 
68 
69 /************************************************************************/
77 /************************************************************************/
78 
79 class RTMIDI_DLL_PUBLIC RtMidiError : public std::exception
80 {
81  public:
83  enum Type {
94  THREAD_ERROR
95  };
96 
98  RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw()
99  : message_(message), type_(type) {}
100 
102  virtual ~RtMidiError( void ) throw() {}
103 
105  virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
106 
108  virtual const Type& getType( void ) const throw() { return type_; }
109 
111  virtual const std::string& getMessage( void ) const throw() { return message_; }
112 
114  virtual const char* what( void ) const throw() { return message_.c_str(); }
115 
116  protected:
117  std::string message_;
118  Type type_;
119 };
120 
122 
129 typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData );
130 
131 class MidiApi;
132 
133 class RTMIDI_DLL_PUBLIC RtMidi
134 {
135  public:
136 
137  RtMidi(RtMidi&& other) noexcept;
139  enum Api {
147  NUM_APIS
148  };
149 
151  static std::string getVersion( void ) throw();
152 
154 
159  static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
160 
162 
167  static std::string getApiName( RtMidi::Api api );
168 
170 
174  static std::string getApiDisplayName( RtMidi::Api api );
175 
177 
182  static RtMidi::Api getCompiledApiByName( const std::string &name );
183 
185  virtual void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi" ) ) = 0;
186 
188  virtual void openVirtualPort( const std::string &portName = std::string( "RtMidi" ) ) = 0;
189 
191  virtual unsigned int getPortCount() = 0;
192 
194  virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
195 
197  virtual void closePort( void ) = 0;
198 
199  void setClientName( const std::string &clientName );
200  void setPortName( const std::string &portName );
201 
203 
207  virtual bool isPortOpen( void ) const = 0;
208 
210 
214  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0;
215 
216  protected:
217  RtMidi();
218  virtual ~RtMidi();
219  MidiApi *rtapi_;
220 
221  /* Make the class non-copyable */
222  RtMidi(RtMidi& other) = delete;
223  RtMidi& operator=(RtMidi& other) = delete;
224 };
225 
226 /**********************************************************************/
240 /**********************************************************************/
241 
242 // **************************************************************** //
243 //
244 // RtMidiIn and RtMidiOut class declarations.
245 //
246 // RtMidiIn / RtMidiOut are "controllers" used to select an available
247 // MIDI input or output interface. They present common APIs for the
248 // user to call but all functionality is implemented by the classes
249 // MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut
250 // each create an instance of a MidiInApi or MidiOutApi subclass based
251 // on the user's API choice. If no choice is made, they attempt to
252 // make a "logical" API selection.
253 //
254 // **************************************************************** //
255 
256 class RTMIDI_DLL_PUBLIC RtMidiIn : public RtMidi
257 {
258  public:
260  typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData );
261 
263 
280  RtMidiIn( RtMidi::Api api=UNSPECIFIED,
281  const std::string& clientName = "RtMidi Input Client",
282  unsigned int queueSizeLimit = 100 );
283 
284  RtMidiIn(RtMidiIn&& other) noexcept : RtMidi(std::move(other)) { }
285 
287  ~RtMidiIn ( void ) throw();
288 
290  RtMidi::Api getCurrentApi( void ) throw();
291 
293 
298  void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Input" ) );
299 
301 
310  void openVirtualPort( const std::string &portName = std::string( "RtMidi Input" ) );
311 
313 
323  void setCallback( RtMidiCallback callback, void *userData = 0 );
324 
326 
330  void cancelCallback();
331 
333  void closePort( void );
334 
336 
340  virtual bool isPortOpen() const;
341 
343 
346  unsigned int getPortCount();
347 
349 
354  std::string getPortName( unsigned int portNumber = 0 );
355 
357 
364  void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
365 
367 
374  double getMessage( std::vector<unsigned char> *message );
375 
377 
381  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
382 
384 
394  virtual void setBufferSize( unsigned int size, unsigned int count );
395 
396  protected:
397  void openMidiApi( RtMidi::Api api, const std::string &clientName, unsigned int queueSizeLimit );
398 };
399 
400 /**********************************************************************/
412 /**********************************************************************/
413 
414 class RTMIDI_DLL_PUBLIC RtMidiOut : public RtMidi
415 {
416  public:
418 
425  RtMidiOut( RtMidi::Api api=UNSPECIFIED,
426  const std::string& clientName = "RtMidi Output Client" );
427 
428  RtMidiOut(RtMidiOut&& other) noexcept : RtMidi(std::move(other)) { }
429 
431  ~RtMidiOut( void ) throw();
432 
434  RtMidi::Api getCurrentApi( void ) throw();
435 
437 
443  void openPort( unsigned int portNumber = 0, const std::string &portName = std::string( "RtMidi Output" ) );
444 
446  void closePort( void );
447 
449 
453  virtual bool isPortOpen() const;
454 
456 
464  void openVirtualPort( const std::string &portName = std::string( "RtMidi Output" ) );
465 
467  unsigned int getPortCount( void );
468 
470 
475  std::string getPortName( unsigned int portNumber = 0 );
476 
478 
482  void sendMessage( const std::vector<unsigned char> *message );
483 
485 
492  void sendMessage( const unsigned char *message, size_t size );
493 
495 
499  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
500 
501  protected:
502  void openMidiApi( RtMidi::Api api, const std::string &clientName );
503 };
504 
505 
506 // **************************************************************** //
507 //
508 // MidiInApi / MidiOutApi class declarations.
509 //
510 // Subclasses of MidiInApi and MidiOutApi contain all API- and
511 // OS-specific code necessary to fully implement the RtMidi API.
512 //
513 // Note that MidiInApi and MidiOutApi are abstract base classes and
514 // cannot be explicitly instantiated. RtMidiIn and RtMidiOut will
515 // create instances of a MidiInApi or MidiOutApi subclass.
516 //
517 // **************************************************************** //
518 
519 class RTMIDI_DLL_PUBLIC MidiApi
520 {
521  public:
522 
523  MidiApi();
524  virtual ~MidiApi();
525  virtual RtMidi::Api getCurrentApi( void ) = 0;
526  virtual void openPort( unsigned int portNumber, const std::string &portName ) = 0;
527  virtual void openVirtualPort( const std::string &portName ) = 0;
528  virtual void closePort( void ) = 0;
529  virtual void setClientName( const std::string &clientName ) = 0;
530  virtual void setPortName( const std::string &portName ) = 0;
531 
532  virtual unsigned int getPortCount( void ) = 0;
533  virtual std::string getPortName( unsigned int portNumber ) = 0;
534 
535  inline bool isPortOpen() const { return connected_; }
536  void setErrorCallback( RtMidiErrorCallback errorCallback, void *userData );
537 
539  void error( RtMidiError::Type type, std::string errorString );
540 
541 protected:
542  virtual void initialize( const std::string& clientName ) = 0;
543 
544  void *apiData_;
545  bool connected_;
546  std::string errorString_;
547  RtMidiErrorCallback errorCallback_;
548  bool firstErrorOccurred_;
549  void *errorCallbackUserData_;
550 
551 };
552 
553 class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
554 {
555  public:
556 
557  MidiInApi( unsigned int queueSizeLimit );
558  virtual ~MidiInApi( void );
559  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
560  void cancelCallback( void );
561  virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
562  double getMessage( std::vector<unsigned char> *message );
563  virtual void setBufferSize( unsigned int size, unsigned int count );
564 
565  // A MIDI structure used internally by the class to store incoming
566  // messages. Each message represents one and only one MIDI message.
567  struct MidiMessage {
568  std::vector<unsigned char> bytes;
569 
571  double timeStamp;
572 
573  // Default constructor.
574  MidiMessage()
575  : bytes(0), timeStamp(0.0) {}
576  };
577 
578  struct MidiQueue {
579  unsigned int front;
580  unsigned int back;
581  unsigned int ringSize;
582  MidiMessage *ring;
583 
584  // Default constructor.
585  MidiQueue()
586  : front(0), back(0), ringSize(0), ring(0) {}
587  bool push( const MidiMessage& );
588  bool pop( std::vector<unsigned char>*, double* );
589  unsigned int size( unsigned int *back=0, unsigned int *front=0 );
590  };
591 
592  // The RtMidiInData structure is used to pass private class data to
593  // the MIDI input handling function or thread.
594  struct RtMidiInData {
595  MidiQueue queue;
596  MidiMessage message;
597  unsigned char ignoreFlags;
598  bool doInput;
599  bool firstMessage;
600  void *apiData;
601  bool usingCallback;
602  RtMidiIn::RtMidiCallback userCallback;
603  void *userData;
604  bool continueSysex;
605  unsigned int bufferSize;
606  unsigned int bufferCount;
607 
608  // Default constructor.
609  RtMidiInData()
610  : ignoreFlags(7), doInput(false), firstMessage(true), apiData(0), usingCallback(false),
611  userCallback(0), userData(0), continueSysex(false), bufferSize(1024), bufferCount(4) {}
612  };
613 
614  protected:
615  RtMidiInData inputData_;
616 };
617 
618 class RTMIDI_DLL_PUBLIC MidiOutApi : public MidiApi
619 {
620  public:
621 
622  MidiOutApi( void );
623  virtual ~MidiOutApi( void );
624  virtual void sendMessage( const unsigned char *message, size_t size ) = 0;
625 };
626 
627 // **************************************************************** //
628 //
629 // Inline RtMidiIn and RtMidiOut definitions.
630 //
631 // **************************************************************** //
632 
633 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
634 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); }
635 inline void RtMidiIn :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
636 inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
637 inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
638 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { static_cast<MidiInApi *>(rtapi_)->setCallback( callback, userData ); }
639 inline void RtMidiIn :: cancelCallback( void ) { static_cast<MidiInApi *>(rtapi_)->cancelCallback(); }
640 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
641 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
642 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { static_cast<MidiInApi *>(rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
643 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return static_cast<MidiInApi *>(rtapi_)->getMessage( message ); }
644 inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
645 inline void RtMidiIn :: setBufferSize( unsigned int size, unsigned int count ) { static_cast<MidiInApi *>(rtapi_)->setBufferSize(size, count); }
646 
647 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
648 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string &portName ) { rtapi_->openPort( portNumber, portName ); }
649 inline void RtMidiOut :: openVirtualPort( const std::string &portName ) { rtapi_->openVirtualPort( portName ); }
650 inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
651 inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
652 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
653 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
654 inline void RtMidiOut :: sendMessage( const std::vector<unsigned char> *message ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( &message->at(0), message->size() ); }
655 inline void RtMidiOut :: sendMessage( const unsigned char *message, size_t size ) { static_cast<MidiOutApi *>(rtapi_)->sendMessage( message, size ); }
656 inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
657 
658 #endif
void(* RtMidiErrorCallback)(RtMidiError::Type type, const std::string &errorText, void *userData)
RtMidi error callback function prototype.
Definition: RtMidi.h:129
Definition: RtMidi.h:520
void error(RtMidiError::Type type, std::string errorString)
A basic error reporting function for RtMidi classes.
Definition: RtMidi.h:554
Definition: RtMidi.h:619
Exception handling class for RtMidi.
Definition: RtMidi.h:80
virtual const std::string & getMessage(void) const
Returns the thrown error message string.
Definition: RtMidi.h:111
virtual const char * what(void) const
Returns the thrown error message as a c-style string.
Definition: RtMidi.h:114
virtual void printMessage(void) const
Prints thrown error message to stderr.
Definition: RtMidi.h:105
Type
Defined RtMidiError types.
Definition: RtMidi.h:83
@ INVALID_USE
Definition: RtMidi.h:91
@ NO_DEVICES_FOUND
Definition: RtMidi.h:87
@ MEMORY_ERROR
Definition: RtMidi.h:89
@ INVALID_PARAMETER
Definition: RtMidi.h:90
@ WARNING
Definition: RtMidi.h:84
@ INVALID_DEVICE
Definition: RtMidi.h:88
@ DRIVER_ERROR
Definition: RtMidi.h:92
@ UNSPECIFIED
Definition: RtMidi.h:86
@ DEBUG_WARNING
Definition: RtMidi.h:85
@ SYSTEM_ERROR
Definition: RtMidi.h:93
virtual const Type & getType(void) const
Returns the thrown error message type.
Definition: RtMidi.h:108
virtual ~RtMidiError(void)
The destructor.
Definition: RtMidi.h:102
RtMidiError(const std::string &message, Type type=RtMidiError::UNSPECIFIED)
The constructor.
Definition: RtMidi.h:98
A realtime MIDI input class.
Definition: RtMidi.h:257
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:643
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:634
void closePort(void)
Close an open MIDI connection (if one exists).
Definition: RtMidi.h:636
unsigned int getPortCount()
Return the number of available MIDI input ports.
Definition: RtMidi.h:640
RtMidi::Api getCurrentApi(void)
Returns the MIDI API specifier for the current instance of RtMidiIn.
Definition: RtMidi.h:633
void setCallback(RtMidiCallback callback, void *userData=0)
Set a callback function to be invoked for incoming MIDI messages.
Definition: RtMidi.h:638
virtual void setBufferSize(unsigned int size, unsigned int count)
Set maximum expected incoming message size.
Definition: RtMidi.h:645
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:635
RtMidiIn(RtMidi::Api api=UNSPECIFIED, const std::string &clientName="RtMidi Input Client", unsigned int queueSizeLimit=100)
Default constructor that allows an optional api, client name and queue size.
virtual bool isPortOpen() const
Returns true if a port is open and false if not.
Definition: RtMidi.h:637
void(* RtMidiCallback)(double timeStamp, std::vector< unsigned char > *message, void *userData)
User callback function type definition.
Definition: RtMidi.h:260
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:644
void cancelCallback()
Cancel use of the current callback function (if one exists).
Definition: RtMidi.h:639
~RtMidiIn(void)
If a MIDI connection is still open, it will be closed by the destructor.
std::string getPortName(unsigned int portNumber=0)
Return a string identifier for the specified MIDI input port number.
Definition: RtMidi.h:641
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:642
A realtime MIDI output class.
Definition: RtMidi.h:415
unsigned int getPortCount(void)
Return the number of available MIDI output ports.
Definition: RtMidi.h:652
void sendMessage(const std::vector< unsigned char > *message)
Immediately send a single message out an open MIDI output port.
Definition: RtMidi.h:654
void openPort(unsigned int portNumber=0, const std::string &portName=std::string("RtMidi Output"))
Open a MIDI output connection.
Definition: RtMidi.h:648
RtMidi::Api getCurrentApi(void)
Returns the MIDI API specifier for the current instance of RtMidiOut.
Definition: RtMidi.h:647
void closePort(void)
Close an open MIDI connection (if one exists).
Definition: RtMidi.h:650
RtMidiOut(RtMidi::Api api=UNSPECIFIED, const std::string &clientName="RtMidi Output Client")
Default constructor that allows an optional client name.
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:649
virtual bool isPortOpen() const
Returns true if a port is open and false if not.
Definition: RtMidi.h:651
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:656
std::string getPortName(unsigned int portNumber=0)
Return a string identifier for the specified MIDI port type and number.
Definition: RtMidi.h:653
~RtMidiOut(void)
The destructor closes any open MIDI connections.
An abstract base class for realtime MIDI input/output.
Definition: RtMidi.h:134
static void getCompiledApi(std::vector< RtMidi::Api > &apis)
A static function to determine the available compiled MIDI APIs.
virtual void openVirtualPort(const std::string &portName=std::string("RtMidi"))=0
Pure virtual openVirtualPort() function.
virtual void closePort(void)=0
Pure virtual closePort() function.
virtual void openPort(unsigned int portNumber=0, const std::string &portName=std::string("RtMidi"))=0
Pure virtual openPort() function.
static std::string getApiDisplayName(RtMidi::Api api)
Return the display name of a specified compiled MIDI API.
virtual bool isPortOpen(void) const =0
Returns true if a port is open and false if not.
static std::string getApiName(RtMidi::Api api)
Return the name of a specified compiled MIDI API.
virtual std::string getPortName(unsigned int portNumber=0)=0
Pure virtual getPortName() function.
static std::string getVersion(void)
A static function to determine the current RtMidi version.
virtual unsigned int getPortCount()=0
Pure virtual getPortCount() function.
static RtMidi::Api getCompiledApiByName(const std::string &name)
Return the compiled MIDI API having the given name.
virtual void setErrorCallback(RtMidiErrorCallback errorCallback=NULL, void *userData=0)=0
Set an error callback function to be invoked when an error has occured.
Api
MIDI API specifier arguments.
Definition: RtMidi.h:139
@ UNIX_JACK
Definition: RtMidi.h:143
@ LINUX_ALSA
Definition: RtMidi.h:142
@ WEB_MIDI_API
Definition: RtMidi.h:146
@ MACOSX_CORE
Definition: RtMidi.h:141
@ UNSPECIFIED
Definition: RtMidi.h:140
@ RTMIDI_DUMMY
Definition: RtMidi.h:145
@ WINDOWS_MM
Definition: RtMidi.h:144
Definition: RtMidi.h:567
double timeStamp
Time in seconds elapsed since the previous message.
Definition: RtMidi.h:571
Definition: RtMidi.h:578
Definition: RtMidi.h:594

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