Forráskód Böngészése

Updates from Mogilevskiy to add error hook, isPortOpen() function, and UNICODE windows name fix.

Gary Scavone 11 éve
szülő
commit
112baabce3
3 módosított fájl, 334 hozzáadás és 193 törlés
  1. 222 131
      RtMidi.cpp
  2. 109 62
      RtMidi.h
  3. 3 0
      doc/release.txt

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 222 - 131
RtMidi.cpp


+ 109 - 62
RtMidi.h

@@ -101,6 +101,18 @@ class RtMidiError : public std::exception
   Type type_;
 };
 
+//! RtMidi error callback function prototype.
+/*!
+    \param type Type of error.
+    \param errorText Error description.
+
+    Note that class behaviour is undefined after a critical error (not
+    a warning) is reported.
+ */
+typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText );
+
+class MidiApi;
+
 class RtMidi
 {
  public:
@@ -143,12 +155,24 @@ class RtMidi
   virtual void closePort( void ) = 0;
 
   //! A basic error reporting function for RtMidi classes.
-  static void error( RtMidiError::Type type, std::string &errorString );
+  //  static void error( RtMidiError::Type type, std::string &errorString );
+
+  //! Returns true if a port is open and false if not.
+  virtual bool isPortOpen( void ) const = 0;
+
+  //! Set an error callback function to be invoked when an error has occured.
+  /*!
+    The callback function will be called whenever an error has occured. It is best
+    to set the error callback function before opening a port.
+  */
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0;
 
  protected:
 
-  RtMidi() {};
-  virtual ~RtMidi() {};
+  RtMidi();
+  virtual ~RtMidi();
+
+  MidiApi *rtapi_;
 };
 
 /**********************************************************************/
@@ -165,7 +189,7 @@ class RtMidi
     to open a virtual input port to which other MIDI software clients
     can connect.
 
-    by Gary P. Scavone, 2003-2012.
+    by Gary P. Scavone, 2003-2014.
 */
 /**********************************************************************/
 
@@ -183,9 +207,6 @@ class RtMidi
 //
 // **************************************************************** //
 
-class MidiInApi;
-class MidiOutApi;
-
 class RtMidiIn : public RtMidi
 {
  public:
@@ -250,6 +271,9 @@ class RtMidiIn : public RtMidi
   //! Close an open MIDI connection (if one exists).
   void closePort( void );
 
+  //! Returns true if a port is open and false if not.
+  virtual bool isPortOpen() const;
+
   //! Return the number of available MIDI input ports.
   unsigned int getPortCount();
 
@@ -279,9 +303,15 @@ class RtMidiIn : public RtMidi
   */
   double getMessage( std::vector<unsigned char> *message );
 
+  //! Set an error callback function to be invoked when an error has occured.
+  /*!
+    The callback function will be called whenever an error has occured. It is best
+    to set the error callback function before opening a port.
+  */
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
+
  protected:
   void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit );
-  MidiInApi *rtapi_;
 
 };
 
@@ -297,7 +327,7 @@ class RtMidiIn : public RtMidi
     OS-X and Linux ALSA MIDI APIs, it is also possible to open a
     virtual port to which other MIDI software clients can connect.
 
-    by Gary P. Scavone, 2003-2012.
+    by Gary P. Scavone, 2003-2014.
 */
 /**********************************************************************/
 
@@ -334,6 +364,9 @@ class RtMidiOut : public RtMidi
   //! Close an open MIDI connection (if one exists).
   void closePort( void );
 
+  //! Returns true if a port is open and false if not.
+  virtual bool isPortOpen() const;
+
   //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only).
   /*!
       This function creates a virtual MIDI output port to which other
@@ -361,9 +394,15 @@ class RtMidiOut : public RtMidi
   */
   void sendMessage( std::vector<unsigned char> *message );
 
+  //! Set an error callback function to be invoked when an error has occured.
+  /*!
+    The callback function will be called whenever an error has occured. It is best
+    to set the error callback function before opening a port.
+  */
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
+
  protected:
   void openMidiApi( RtMidi::Api api, const std::string clientName );
-  MidiOutApi *rtapi_;
 };
 
 
@@ -380,22 +419,46 @@ class RtMidiOut : public RtMidi
 //
 // **************************************************************** //
 
-class MidiInApi
+class MidiApi
 {
  public:
 
-  MidiInApi( unsigned int queueSizeLimit );
-  virtual ~MidiInApi( void );
+  MidiApi();
+  virtual ~MidiApi();
   virtual RtMidi::Api getCurrentApi( void ) = 0;
   virtual void openPort( unsigned int portNumber, const std::string portName ) = 0;
   virtual void openVirtualPort( const std::string portName ) = 0;
   virtual void closePort( void ) = 0;
-  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
-  void cancelCallback( void );
+
   virtual unsigned int getPortCount( void ) = 0;
   virtual std::string getPortName( unsigned int portNumber ) = 0;
+
+  bool isPortOpened() const;
+  void setErrorCallback( RtMidiErrorCallback errorCallback );
+
+  //! A basic error reporting function for RtMidi classes.
+  void error( RtError::Type type, std::string errorString );
+
+protected:
+  virtual void initialize( const std::string& clientName ) = 0;
+
+  void *apiData_;
+  bool connected_;
+  std::string errorString_;
+  RtMidiErrorCallback errorCallback_;
+}
+
+class MidiInApi : public MidiApi
+{
+ public:
+
+  MidiInApi( unsigned int queueSizeLimit );
+  virtual ~MidiInApi( void );
+  void setCallback( RtMidiIn::RtMidiCallback callback, void *userData );
+  void cancelCallback( void );
   virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense );
   double getMessage( std::vector<unsigned char> *message );
+  inline bool isPortOpen() const { return connected_; }
 
   // A MIDI structure used internally by the class to store incoming
   // messages.  Each message represents one and only one MIDI message.
@@ -442,34 +505,16 @@ class MidiInApi
   };
 
  protected:
-  virtual void initialize( const std::string& clientName ) = 0;
   RtMidiInData inputData_;
-
-  void *apiData_;
-  bool connected_;
-  std::string errorString_;
 };
 
-class MidiOutApi
+class MidiOutApi : public MidiApi
 {
  public:
 
   MidiOutApi( void );
   virtual ~MidiOutApi( void );
-  virtual RtMidi::Api getCurrentApi( void ) = 0;
-  virtual void openPort( unsigned int portNumber, const std::string portName ) = 0;
-  virtual void openVirtualPort( const std::string portName ) = 0;
-  virtual void closePort( void ) = 0;
-  virtual unsigned int getPortCount( void ) = 0;
-  virtual std::string getPortName( unsigned int portNumber ) = 0;
   virtual void sendMessage( std::vector<unsigned char> *message ) = 0;
-
- protected:
-  virtual void initialize( const std::string& clientName ) = 0;
-
-  void *apiData_;
-  bool connected_;
-  std::string errorString_;
 };
 
 // **************************************************************** //
@@ -479,23 +524,25 @@ class MidiOutApi
 // **************************************************************** //
 
 inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
-inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { return rtapi_->openPort( portNumber, portName ); }
-inline void RtMidiIn :: openVirtualPort( const std::string portName ) { return rtapi_->openVirtualPort( portName ); }
-inline void RtMidiIn :: closePort( void ) { return rtapi_->closePort(); }
-inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { return rtapi_->setCallback( callback, userData ); }
-inline void RtMidiIn :: cancelCallback( void ) { return rtapi_->cancelCallback(); }
+inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
+inline void RtMidiIn :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
+inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); }
+inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { ((MidiInApi *)rtapi_)->setCallback( callback, userData ); }
+inline void RtMidiIn :: cancelCallback( void ) { ((MidiInApi *)rtapi_)->cancelCallback(); }
 inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); }
 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
-inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { return rtapi_->ignoreTypes( midiSysex, midiTime, midiSense ); }
-inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return rtapi_->getMessage( message ); }
+inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
+inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
+inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
 
 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
-inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { return rtapi_->openPort( portNumber, portName ); }
-inline void RtMidiOut :: openVirtualPort( const std::string portName ) { return rtapi_->openVirtualPort( portName ); }
-inline void RtMidiOut :: closePort( void ) { return rtapi_->closePort(); }
+inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
+inline void RtMidiOut :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); }
+inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); }
 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
-inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { return rtapi_->sendMessage( message ); }
+inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
+inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
 
 // **************************************************************** //
 //
@@ -703,32 +750,32 @@ class MidiOutWinKS: public MidiOutApi
 class MidiInDummy: public MidiInApi
 {
  public:
- MidiInDummy( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; RtMidi::error( RtMidiError::WARNING, errorString_ ); };
-  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; };
-  void openPort( unsigned int portNumber, const std::string portName ) {};
-  void openVirtualPort( const std::string portName ) {};
-  void closePort( void ) {};
-  unsigned int getPortCount( void ) { return 0; };
-  std::string getPortName( unsigned int portNumber ) { return ""; };
+ MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
+  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
+  void openVirtualPort( const std::string /*portName*/ ) {}
+  void closePort( void ) {}
+  unsigned int getPortCount( void ) { return 0; }
+  std::string getPortName( unsigned int portNumber ) { return ""; }
 
  protected:
-  void initialize( const std::string& clientName ) {};
+  void initialize( const std::string& /*clientName*/ ) {}
 };
 
 class MidiOutDummy: public MidiOutApi
 {
  public:
-  MidiOutDummy( const std::string clientName ) { errorString_ = "MidiOutDummy: This class provides no functionality."; RtMidi::error( RtMidiError::WARNING, errorString_ ); };
-  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; };
-  void openPort( unsigned int portNumber, const std::string portName ) {};
-  void openVirtualPort( const std::string portName ) {};
-  void closePort( void ) {};
-  unsigned int getPortCount( void ) { return 0; };
-  std::string getPortName( unsigned int portNumber ) { return ""; };
-  void sendMessage( std::vector<unsigned char> *message ) {};
+  MidiOutDummy( const std::string /*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); }
+  RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }
+  void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {}
+  void openVirtualPort( const std::string /*portName*/ ) {}
+  void closePort( void ) {}
+  unsigned int getPortCount( void ) { return 0; }
+  std::string getPortName( unsigned int /*portNumber*/ ) { return ""; }
+  void sendMessage( std::vector<unsigned char> * /*message*/ ) {}
 
  protected:
-  void initialize( const std::string& clientName ) {};
+  void initialize( const std::string& /*clientName*/ ) {}
 };
 
 #endif

+ 3 - 0
doc/release.txt

@@ -10,6 +10,9 @@ v2.1.0: (?? 2014)
 - fix for ALSA incorrect use of snd_seq_create_port() function (Tobias Schlemmer)
 - fix for international character support in CoreMidi (Martin Finke)
 - fix for unicode conversion in WinMM (Dan Wilcox)
+- added custom error hook that allows the client to capture an RtMidi error outside of the RtMidi code
+- fix for portnames in Windows when UNICODE is defined
+- added RtMidi::isPortOpen function
 
 v2.0.1: (26 July 2012)
 - small fixes for problems reported by Chris Arndt (scoping, preprocessor, and include)

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott