Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


RtMidi.h
Go to the documentation of this file.
1 /**********************************************************************/
37 /**********************************************************************/
38 
43 #ifndef RTMIDI_H
44 #define RTMIDI_H
45 
46 #define RTMIDI_VERSION "2.1.0"
47 
48 #include <exception>
49 #include <iostream>
50 #include <string>
51 #include <vector>
52 
53 /************************************************************************/
61 /************************************************************************/
62 
63 class RtMidiError : public std::exception
64 {
65  public:
67  enum Type {
79  };
80 
82  RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
83 
85  virtual ~RtMidiError( void ) throw() {}
86 
88  virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
89 
91  virtual const Type& getType(void) const throw() { return type_; }
92 
94  virtual const std::string& getMessage(void) const throw() { return message_; }
95 
97  virtual const char* what( void ) const throw() { return message_.c_str(); }
98 
99  protected:
100  std::string message_;
101  Type type_;
102 };
103 
105 
112 typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText );
113 
114 class MidiApi;
115 
116 class RtMidi
117 {
118  public:
119 
121  enum Api {
128  };
129 
131  static std::string getVersion( void ) throw();
132 
134 
139  static void getCompiledApi( std::vector<RtMidi::Api> &apis ) throw();
140 
142  virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0;
143 
145  virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0;
146 
148  virtual unsigned int getPortCount() = 0;
149 
151  virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
152 
154  virtual void closePort( void ) = 0;
155 
157  virtual bool isPortOpen( void ) const = 0;
158 
160 
164  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0;
165 
166  protected:
167 
168  RtMidi();
169  virtual ~RtMidi();
170 
171  MidiApi *rtapi_;
172 };
173 
174 /**********************************************************************/
190 /**********************************************************************/
191 
192 // **************************************************************** //
193 //
194 // RtMidiIn and RtMidiOut class declarations.
195 //
196 // RtMidiIn / RtMidiOut are "controllers" used to select an available
197 // MIDI input or output interface. They present common APIs for the
198 // user to call but all functionality is implemented by the classes
199 // MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut
200 // each create an instance of a MidiInApi or MidiOutApi subclass based
201 // on the user's API choice. If no choice is made, they attempt to
202 // make a "logical" API selection.
203 //
204 // **************************************************************** //
205 
206 class RtMidiIn : public RtMidi
207 {
208  public:
209 
211  typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
212 
214 
232  const std::string clientName = std::string( "RtMidi Input Client"),
233  unsigned int queueSizeLimit = 100 );
234 
236  ~RtMidiIn ( void ) throw();
237 
239  RtMidi::Api getCurrentApi( void ) throw();
240 
242 
247  void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) );
248 
250 
259  void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) );
260 
262 
272  void setCallback( RtMidiCallback callback, void *userData = 0 );
273 
275 
279  void cancelCallback();
280 
282  void closePort( void );
283 
285  virtual bool isPortOpen() const;
286 
288 
291  unsigned int getPortCount();
292 
294 
298  std::string getPortName( unsigned int portNumber = 0 );
299 
301 
308  void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true );
309 
311 
318  double getMessage( std::vector<unsigned char> *message );
319 
321 
325  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
326 
327  protected:
328  void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit );
329 
330 };
331 
332 /**********************************************************************/
346 /**********************************************************************/
347 
348 class RtMidiOut : public RtMidi
349 {
350  public:
351 
353 
361  const std::string clientName = std::string( "RtMidi Output Client") );
362 
364  ~RtMidiOut( void ) throw();
365 
367  RtMidi::Api getCurrentApi( void ) throw();
368 
370 
376  void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) );
377 
379  void closePort( void );
380 
382  virtual bool isPortOpen() const;
383 
385 
393  void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) );
394 
396  unsigned int getPortCount( void );
397 
399 
402  std::string getPortName( unsigned int portNumber = 0 );
403 
405 
409  void sendMessage( std::vector<unsigned char> *message );
410 
412 
416  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
417 
418  protected:
419  void openMidiApi( RtMidi::Api api, const std::string clientName );
420 };
421 
422 
423 // **************************************************************** //
424 //
425 // MidiInApi / MidiOutApi class declarations.
426 //
427 // Subclasses of MidiInApi and MidiOutApi contain all API- and
428 // OS-specific code necessary to fully implement the RtMidi API.
429 //
430 // Note that MidiInApi and MidiOutApi are abstract base classes and
431 // cannot be explicitly instantiated. RtMidiIn and RtMidiOut will
432 // create instances of a MidiInApi or MidiOutApi subclass.
433 //
434 // **************************************************************** //
435 
436 class MidiApi
437 {
438  public:
439 
440  MidiApi();
441  virtual ~MidiApi();
442  virtual RtMidi::Api getCurrentApi( void ) = 0;
443  virtual void openPort( unsigned int portNumber, const std::string portName ) = 0;
444  virtual void openVirtualPort( const std::string portName ) = 0;
445  virtual void closePort( void ) = 0;
446 
447  virtual unsigned int getPortCount( void ) = 0;
448  virtual std::string getPortName( unsigned int portNumber ) = 0;
449 
450  inline bool isPortOpen() const { return connected_; }
451  void setErrorCallback( RtMidiErrorCallback errorCallback );
452 
454  void error( RtMidiError::Type type, std::string errorString );
455 
456 protected:
457  virtual void initialize( const std::string& clientName ) = 0;
458 
459  void *apiData_;
460  bool connected_;
461  std::string errorString_;
462  RtMidiErrorCallback errorCallback_;
463 };
464 
465 class MidiInApi : public MidiApi
466 {
467  public:
468 
469  MidiInApi( unsigned int queueSizeLimit );
470  virtual ~MidiInApi( void );
471  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
472  void cancelCallback( void );
473  virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
474  double getMessage( std::vector<unsigned char> *message );
475 
476  // A MIDI structure used internally by the class to store incoming
477  // messages. Each message represents one and only one MIDI message.
478  struct MidiMessage {
479  std::vector<unsigned char> bytes;
480  double timeStamp;
481 
482  // Default constructor.
483  MidiMessage()
484  :bytes(0), timeStamp(0.0) {}
485  };
486 
487  struct MidiQueue {
488  unsigned int front;
489  unsigned int back;
490  unsigned int size;
491  unsigned int ringSize;
492  MidiMessage *ring;
493 
494  // Default constructor.
495  MidiQueue()
496  :front(0), back(0), size(0), ringSize(0) {}
497  };
498 
499  // The RtMidiInData structure is used to pass private class data to
500  // the MIDI input handling function or thread.
501  struct RtMidiInData {
502  MidiQueue queue;
503  MidiMessage message;
504  unsigned char ignoreFlags;
505  bool doInput;
506  bool firstMessage;
507  void *apiData;
508  bool usingCallback;
509  RtMidiIn::RtMidiCallback userCallback;
510  void *userData;
511  bool continueSysex;
512 
513  // Default constructor.
514  RtMidiInData()
515  : ignoreFlags(7), doInput(false), firstMessage(true),
516  apiData(0), usingCallback(false), userCallback(0), userData(0),
517  continueSysex(false) {}
518  };
519 
520  protected:
521  RtMidiInData inputData_;
522 };
523 
524 class MidiOutApi : public MidiApi
525 {
526  public:
527 
528  MidiOutApi( void );
529  virtual ~MidiOutApi( void );
530  virtual void sendMessage( std::vector<unsigned char> *message ) = 0;
531 };
532 
533 // **************************************************************** //
534 //
535 // Inline RtMidiIn and RtMidiOut definitions.
536 //
537 // **************************************************************** //
538 
539 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
540 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
541 inline void RtMidiIn :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
542 inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
543 inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
544 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { ((MidiInApi *)rtapi_)->setCallback( callback, userData ); }
545 inline void RtMidiIn :: cancelCallback( void ) { ((MidiInApi *)rtapi_)->cancelCallback(); }
546 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
547 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
548 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
549 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
550 inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
551 
552 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
553 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
554 inline void RtMidiOut :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
555 inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
556 inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
557 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
558 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
559 inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
560 inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
561 
562 // **************************************************************** //
563 //
564 // MidiInApi and MidiOutApi subclass prototypes.
565 //
566 // **************************************************************** //
567 
568 #if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__)
569  #define __RTMIDI_DUMMY__
570 #endif
571 
572 #if defined(__MACOSX_CORE__)
573 
574 class MidiInCore: public MidiInApi
575 {
576  public:
577  MidiInCore( const std::string clientName, unsigned int queueSizeLimit );
578  ~MidiInCore( void );
579  RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
580  void openPort( unsigned int portNumber, const std::string portName );
581  void openVirtualPort( const std::string portName );
582  void closePort( void );
583  unsigned int getPortCount( void );
584  std::string getPortName( unsigned int portNumber );
585 
586  protected:
587  void initialize( const std::string& clientName );
588 };
589 
590 class MidiOutCore: public MidiOutApi
591 {
592  public:
593  MidiOutCore( const std::string clientName );
594  ~MidiOutCore( void );
595  RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
596  void openPort( unsigned int portNumber, const std::string portName );
597  void openVirtualPort( const std::string portName );
598  void closePort( void );
599  unsigned int getPortCount( void );
600  std::string getPortName( unsigned int portNumber );
601  void sendMessage( std::vector<unsigned char> *message );
602 
603  protected:
604  void initialize( const std::string& clientName );
605 };
606 
607 #endif
608 
609 #if defined(__UNIX_JACK__)
610 
611 class MidiInJack: public MidiInApi
612 {
613  public:
614  MidiInJack( const std::string clientName, unsigned int queueSizeLimit );
615  ~MidiInJack( void );
616  RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
617  void openPort( unsigned int portNumber, const std::string portName );
618  void openVirtualPort( const std::string portName );
619  void closePort( void );
620  unsigned int getPortCount( void );
621  std::string getPortName( unsigned int portNumber );
622 
623  protected:
624  std::string clientName;
625 
626  void connect( void );
627  void initialize( const std::string& clientName );
628 };
629 
630 class MidiOutJack: public MidiOutApi
631 {
632  public:
633  MidiOutJack( const std::string clientName );
634  ~MidiOutJack( void );
635  RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
636  void openPort( unsigned int portNumber, const std::string portName );
637  void openVirtualPort( const std::string portName );
638  void closePort( void );
639  unsigned int getPortCount( void );
640  std::string getPortName( unsigned int portNumber );
641  void sendMessage( std::vector<unsigned char> *message );
642 
643  protected:
644  std::string clientName;
645 
646  void connect( void );
647  void initialize( const std::string& clientName );
648 };
649 
650 #endif
651 
652 #if defined(__LINUX_ALSA__)
653 
654 class MidiInAlsa: public MidiInApi
655 {
656  public:
657  MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit );
658  ~MidiInAlsa( void );
659  RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
660  void openPort( unsigned int portNumber, const std::string portName );
661  void openVirtualPort( const std::string portName );
662  void closePort( void );
663  unsigned int getPortCount( void );
664  std::string getPortName( unsigned int portNumber );
665 
666  protected:
667  void initialize( const std::string& clientName );
668 };
669 
670 class MidiOutAlsa: public MidiOutApi
671 {
672  public:
673  MidiOutAlsa( const std::string clientName );
674  ~MidiOutAlsa( void );
675  RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
676  void openPort( unsigned int portNumber, const std::string portName );
677  void openVirtualPort( const std::string portName );
678  void closePort( void );
679  unsigned int getPortCount( void );
680  std::string getPortName( unsigned int portNumber );
681  void sendMessage( std::vector<unsigned char> *message );
682 
683  protected:
684  void initialize( const std::string& clientName );
685 };
686 
687 #endif
688 
689 #if defined(__WINDOWS_MM__)
690 
691 class MidiInWinMM: public MidiInApi
692 {
693  public:
694  MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit );
695  ~MidiInWinMM( void );
696  RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
697  void openPort( unsigned int portNumber, const std::string portName );
698  void openVirtualPort( const std::string portName );
699  void closePort( void );
700  unsigned int getPortCount( void );
701  std::string getPortName( unsigned int portNumber );
702 
703  protected:
704  void initialize( const std::string& clientName );
705 };
706 
707 class MidiOutWinMM: public MidiOutApi
708 {
709  public:
710  MidiOutWinMM( const std::string clientName );
711  ~MidiOutWinMM( void );
712  RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
713  void openPort( unsigned int portNumber, const std::string portName );
714  void openVirtualPort( const std::string portName );
715  void closePort( void );
716  unsigned int getPortCount( void );
717  std::string getPortName( unsigned int portNumber );
718  void sendMessage( std::vector<unsigned char> *message );
719 
720  protected:
721  void initialize( const std::string& clientName );
722 };
723 
724 #endif
725 
726 #if defined(__RTMIDI_DUMMY__)
727 
728 class MidiInDummy: public MidiInApi
729 {
730  public:
731  MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
732  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
733  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
734  void openVirtualPort( const std::string /*portName*/ ) {}
735  void closePort( void ) {}
736  unsigned int getPortCount( void ) { return 0; }
737  std::string getPortName( unsigned int portNumber ) { return ""; }
738 
739  protected:
740  void initialize( const std::string& /*clientName*/ ) {}
741 };
742 
743 class MidiOutDummy: public MidiOutApi
744 {
745  public:
746  MidiOutDummy( const std::string /*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
747  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
748  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
749  void openVirtualPort( const std::string /*portName*/ ) {}
750  void closePort( void ) {}
751  unsigned int getPortCount( void ) { return 0; }
752  std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
753  void sendMessage( std::vector<unsigned char> * /*message*/ ) {}
754 
755  protected:
756  void initialize( const std::string& /*clientName*/ ) {}
757 };
758 
759 #endif
760 
761 #endif

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