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.1"
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, void *userData );
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, void *userData = 0 ) = 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, void *userData = 0 );
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, void *userData = 0 );
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, void *userData );
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  bool firstErrorOccurred_;
464  void *errorCallbackUserData_;
465 };
466 
467 class MidiInApi : public MidiApi
468 {
469  public:
470 
471  MidiInApi( unsigned int queueSizeLimit );
472  virtual ~MidiInApi( void );
473  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
474  void cancelCallback( void );
475  virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
476  double getMessage( std::vector<unsigned char> *message );
477 
478  // A MIDI structure used internally by the class to store incoming
479  // messages. Each message represents one and only one MIDI message.
480  struct MidiMessage {
481  std::vector<unsigned char> bytes;
482  double timeStamp;
483 
484  // Default constructor.
485  MidiMessage()
486  :bytes(0), timeStamp(0.0) {}
487  };
488 
489  struct MidiQueue {
490  unsigned int front;
491  unsigned int back;
492  unsigned int size;
493  unsigned int ringSize;
494  MidiMessage *ring;
495 
496  // Default constructor.
497  MidiQueue()
498  :front(0), back(0), size(0), ringSize(0) {}
499  };
500 
501  // The RtMidiInData structure is used to pass private class data to
502  // the MIDI input handling function or thread.
503  struct RtMidiInData {
504  MidiQueue queue;
505  MidiMessage message;
506  unsigned char ignoreFlags;
507  bool doInput;
508  bool firstMessage;
509  void *apiData;
510  bool usingCallback;
511  RtMidiIn::RtMidiCallback userCallback;
512  void *userData;
513  bool continueSysex;
514 
515  // Default constructor.
516  RtMidiInData()
517  : ignoreFlags(7), doInput(false), firstMessage(true),
518  apiData(0), usingCallback(false), userCallback(0), userData(0),
519  continueSysex(false) {}
520  };
521 
522  protected:
523  RtMidiInData inputData_;
524 };
525 
526 class MidiOutApi : public MidiApi
527 {
528  public:
529 
530  MidiOutApi( void );
531  virtual ~MidiOutApi( void );
532  virtual void sendMessage( std::vector<unsigned char> *message ) = 0;
533 };
534 
535 // **************************************************************** //
536 //
537 // Inline RtMidiIn and RtMidiOut definitions.
538 //
539 // **************************************************************** //
540 
541 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
542 inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
543 inline void RtMidiIn :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
544 inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
545 inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); }
546 inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { ((MidiInApi *)rtapi_)->setCallback( callback, userData ); }
547 inline void RtMidiIn :: cancelCallback( void ) { ((MidiInApi *)rtapi_)->cancelCallback(); }
548 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
549 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
550 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
551 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
552 inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
553 
554 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
555 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
556 inline void RtMidiOut :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
557 inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
558 inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
559 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
560 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
561 inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
562 inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
563 
564 // **************************************************************** //
565 //
566 // MidiInApi and MidiOutApi subclass prototypes.
567 //
568 // **************************************************************** //
569 
570 #if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__)
571  #define __RTMIDI_DUMMY__
572 #endif
573 
574 #if defined(__MACOSX_CORE__)
575 
576 class MidiInCore: public MidiInApi
577 {
578  public:
579  MidiInCore( const std::string clientName, unsigned int queueSizeLimit );
580  ~MidiInCore( void );
581  RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
582  void openPort( unsigned int portNumber, const std::string portName );
583  void openVirtualPort( const std::string portName );
584  void closePort( void );
585  unsigned int getPortCount( void );
586  std::string getPortName( unsigned int portNumber );
587 
588  protected:
589  void initialize( const std::string& clientName );
590 };
591 
592 class MidiOutCore: public MidiOutApi
593 {
594  public:
595  MidiOutCore( const std::string clientName );
596  ~MidiOutCore( void );
597  RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; };
598  void openPort( unsigned int portNumber, const std::string portName );
599  void openVirtualPort( const std::string portName );
600  void closePort( void );
601  unsigned int getPortCount( void );
602  std::string getPortName( unsigned int portNumber );
603  void sendMessage( std::vector<unsigned char> *message );
604 
605  protected:
606  void initialize( const std::string& clientName );
607 };
608 
609 #endif
610 
611 #if defined(__UNIX_JACK__)
612 
613 class MidiInJack: public MidiInApi
614 {
615  public:
616  MidiInJack( const std::string clientName, unsigned int queueSizeLimit );
617  ~MidiInJack( void );
618  RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
619  void openPort( unsigned int portNumber, const std::string portName );
620  void openVirtualPort( const std::string portName );
621  void closePort( void );
622  unsigned int getPortCount( void );
623  std::string getPortName( unsigned int portNumber );
624 
625  protected:
626  std::string clientName;
627 
628  void connect( void );
629  void initialize( const std::string& clientName );
630 };
631 
632 class MidiOutJack: public MidiOutApi
633 {
634  public:
635  MidiOutJack( const std::string clientName );
636  ~MidiOutJack( void );
637  RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; };
638  void openPort( unsigned int portNumber, const std::string portName );
639  void openVirtualPort( const std::string portName );
640  void closePort( void );
641  unsigned int getPortCount( void );
642  std::string getPortName( unsigned int portNumber );
643  void sendMessage( std::vector<unsigned char> *message );
644 
645  protected:
646  std::string clientName;
647 
648  void connect( void );
649  void initialize( const std::string& clientName );
650 };
651 
652 #endif
653 
654 #if defined(__LINUX_ALSA__)
655 
656 class MidiInAlsa: public MidiInApi
657 {
658  public:
659  MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit );
660  ~MidiInAlsa( void );
661  RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
662  void openPort( unsigned int portNumber, const std::string portName );
663  void openVirtualPort( const std::string portName );
664  void closePort( void );
665  unsigned int getPortCount( void );
666  std::string getPortName( unsigned int portNumber );
667 
668  protected:
669  void initialize( const std::string& clientName );
670 };
671 
672 class MidiOutAlsa: public MidiOutApi
673 {
674  public:
675  MidiOutAlsa( const std::string clientName );
676  ~MidiOutAlsa( void );
677  RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; };
678  void openPort( unsigned int portNumber, const std::string portName );
679  void openVirtualPort( const std::string portName );
680  void closePort( void );
681  unsigned int getPortCount( void );
682  std::string getPortName( unsigned int portNumber );
683  void sendMessage( std::vector<unsigned char> *message );
684 
685  protected:
686  void initialize( const std::string& clientName );
687 };
688 
689 #endif
690 
691 #if defined(__WINDOWS_MM__)
692 
693 class MidiInWinMM: public MidiInApi
694 {
695  public:
696  MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit );
697  ~MidiInWinMM( void );
698  RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
699  void openPort( unsigned int portNumber, const std::string portName );
700  void openVirtualPort( const std::string portName );
701  void closePort( void );
702  unsigned int getPortCount( void );
703  std::string getPortName( unsigned int portNumber );
704 
705  protected:
706  void initialize( const std::string& clientName );
707 };
708 
709 class MidiOutWinMM: public MidiOutApi
710 {
711  public:
712  MidiOutWinMM( const std::string clientName );
713  ~MidiOutWinMM( void );
714  RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; };
715  void openPort( unsigned int portNumber, const std::string portName );
716  void openVirtualPort( const std::string portName );
717  void closePort( void );
718  unsigned int getPortCount( void );
719  std::string getPortName( unsigned int portNumber );
720  void sendMessage( std::vector<unsigned char> *message );
721 
722  protected:
723  void initialize( const std::string& clientName );
724 };
725 
726 #endif
727 
728 #if defined(__RTMIDI_DUMMY__)
729 
730 class MidiInDummy: public MidiInApi
731 {
732  public:
733  MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
734  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
735  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
736  void openVirtualPort( const std::string /*portName*/ ) {}
737  void closePort( void ) {}
738  unsigned int getPortCount( void ) { return 0; }
739  std::string getPortName( unsigned int portNumber ) { return ""; }
740 
741  protected:
742  void initialize( const std::string& /*clientName*/ ) {}
743 };
744 
745 class MidiOutDummy: public MidiOutApi
746 {
747  public:
748  MidiOutDummy( const std::string /*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
749  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
750  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
751  void openVirtualPort( const std::string /*portName*/ ) {}
752  void closePort( void ) {}
753  unsigned int getPortCount( void ) { return 0; }
754  std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
755  void sendMessage( std::vector<unsigned char> * /*message*/ ) {}
756 
757  protected:
758  void initialize( const std::string& /*clientName*/ ) {}
759 };
760 
761 #endif
762 
763 #endif

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