diff --git a/RtMidi.cpp b/RtMidi.cpp index 07e23168..a44e4b0c 100644 --- a/RtMidi.cpp +++ b/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() diff --git a/RtMidi.h b/RtMidi.h index 9a878884..622cf79b 100644 --- a/RtMidi.h +++ b/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 @@ class MidiApi 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 *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 *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); } // **************************************************************** // //