Просмотр исходного кода

Memory leak fix in CoreMidi and addition of UserData pointer to error callback.

Gary Scavone 11 лет назад
Родитель
Сommit
2c7a6664d6
2 измененных файлов с 18 добавлено и 12 удалено
  1. 10 5
      RtMidi.cpp
  2. 8 7
      RtMidi.h

+ 10 - 5
RtMidi.cpp

@@ -224,7 +224,7 @@ RtMidiOut :: ~RtMidiOut() throw()
 //*********************************************************************//
 
 MidiApi :: MidiApi( void )
-  : apiData_( 0 ), connected_( false ), errorCallback_(0)
+  : apiData_( 0 ), connected_( false ), errorCallback_(0), errorCallbackUserData_(0)
 {
 }
 
@@ -232,9 +232,10 @@ MidiApi :: ~MidiApi( void )
 {
 }
 
-void MidiApi :: setErrorCallback( RtMidiErrorCallback errorCallback )
+void MidiApi :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData = 0 )
 {
     errorCallback_ = errorCallback;
+    errorCallbackUserData_ = userData;
 }
 
 void MidiApi :: error( RtMidiError::Type type, std::string errorString )
@@ -248,7 +249,7 @@ void MidiApi :: error( RtMidiError::Type type, std::string errorString )
     firstErrorOccured = true;
     const std::string errorMessage = errorString;
 
-    errorCallback_( type, errorMessage );
+    errorCallback_( type, errorMessage, errorCallbackUserData_);
     firstErrorOccured = false;
     return;
   }
@@ -567,7 +568,8 @@ void MidiInCore :: initialize( const std::string& clientName )
 {
   // Set up our client.
   MIDIClientRef client;
-  OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
+  CFStringRef name = CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII );
+  OSStatus result = MIDIClientCreate(name, NULL, NULL, &client );
   if ( result != noErr ) {
     errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object.";
     error( RtMidiError::DRIVER_ERROR, errorString_ );
@@ -580,6 +582,7 @@ void MidiInCore :: initialize( const std::string& clientName )
   data->endpoint = 0;
   apiData_ = (void *) data;
   inputData_.apiData = (void *) data;
+  CFRelease(name);
 }
 
 void MidiInCore :: openPort( unsigned int portNumber, const std::string portName )
@@ -852,7 +855,8 @@ void MidiOutCore :: initialize( const std::string& clientName )
 {
   // Set up our client.
   MIDIClientRef client;
-  OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
+  CFStringRef name = CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII );
+  OSStatus result = MIDIClientCreate(name, NULL, NULL, &client );
   if ( result != noErr ) {
     errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object.";
     error( RtMidiError::DRIVER_ERROR, errorString_ );
@@ -864,6 +868,7 @@ void MidiOutCore :: initialize( const std::string& clientName )
   data->client = client;
   data->endpoint = 0;
   apiData_ = (void *) data;
+  CFRelease( name );
 }
 
 unsigned int MidiOutCore :: getPortCount()

+ 8 - 7
RtMidi.h

@@ -109,7 +109,7 @@ class RtMidiError : public std::exception
     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 );
+typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData );
 
 class MidiApi;
 
@@ -161,7 +161,7 @@ class RtMidi
     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;
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0;
 
  protected:
 
@@ -322,7 +322,7 @@ class RtMidiIn : public RtMidi
     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 );
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
 
  protected:
   void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit );
@@ -413,7 +413,7 @@ class RtMidiOut : public RtMidi
     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 );
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
 
  protected:
   void openMidiApi( RtMidi::Api api, const std::string clientName );
@@ -448,7 +448,7 @@ class MidiApi
   virtual std::string getPortName( unsigned int portNumber ) = 0;
 
   inline bool isPortOpen() const { return connected_; }
-  void setErrorCallback( RtMidiErrorCallback errorCallback );
+  void setErrorCallback( RtMidiErrorCallback errorCallback, void *userData );
 
   //! A basic error reporting function for RtMidi classes.
   void error( RtMidiError::Type type, std::string errorString );
@@ -460,6 +460,7 @@ protected:
   bool connected_;
   std::string errorString_;
   RtMidiErrorCallback errorCallback_;
+  void *errorCallbackUserData_;
 };
 
 class MidiInApi : public MidiApi
@@ -547,7 +548,7 @@ inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCou
 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
 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 void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
 
 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
@@ -557,7 +558,7 @@ inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
 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 ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
-inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
+inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
 
 // **************************************************************** //
 //