Skip to content

Commit

Permalink
Memory leak fix in CoreMidi and addition of UserData pointer to error…
Browse files Browse the repository at this point in the history
… callback.
  • Loading branch information
garyscavone committed Jun 6, 2014
1 parent f488872 commit 2c7a666
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
15 changes: 10 additions & 5 deletions RtMidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,18 @@ RtMidiOut :: ~RtMidiOut() throw()
//*********************************************************************//

MidiApi :: MidiApi( void )
: apiData_( 0 ), connected_( false ), errorCallback_(0)
: apiData_( 0 ), connected_( false ), errorCallback_(0), errorCallbackUserData_(0)
{
}

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 )
Expand All @@ -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;
}
Expand Down Expand Up @@ -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_ );
Expand All @@ -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 )
Expand Down Expand Up @@ -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_ );
Expand All @@ -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()
Expand Down
15 changes: 8 additions & 7 deletions RtMidi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand All @@ -460,6 +460,7 @@ class MidiApi
bool connected_;
std::string errorString_;
RtMidiErrorCallback errorCallback_;
void *errorCallbackUserData_;
};

class MidiInApi : public MidiApi
Expand Down Expand Up @@ -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 ); }
Expand All @@ -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); }

// **************************************************************** //
//
Expand Down

0 comments on commit 2c7a666

Please sign in to comment.