Skip to content

Commit

Permalink
introduced MIDIClientRef singleton for macos
Browse files Browse the repository at this point in the history
  • Loading branch information
tschiemer committed May 9, 2020
1 parent 523cada commit 825c5a4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 30 deletions.
68 changes: 38 additions & 30 deletions RtMidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ MidiOutApi :: ~MidiOutApi( void )
// time values.

// OS-X CoreMIDI header files.
#include <CoreMIDI/CoreMIDI.h>

#include <CoreAudio/HostTime.h>
#include <CoreServices/CoreServices.h>

Expand All @@ -732,6 +732,41 @@ struct CoreMidiData {
MIDISysexSendRequest sysexreq;
};


MIDIClientRef MidiApi::CoreMidiClientSingleton = 0;

MIDIClientRef MidiApi::getCoreMidiClientSingleton(const std::string& clientName) throw() {

if (CoreMidiClientSingleton == 0){
// Set up our client.
MIDIClientRef client;

CFStringRef name = CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII );
OSStatus result = MIDIClientCreate(name, NULL, NULL, &client );
if ( result != noErr ) {
std::ostringstream ost;
ost << "MidiInCore::initialize: error creating OS-X MIDI client object (" << result << ").";
errorString_ = ost.str();
error( RtMidiError::DRIVER_ERROR, errorString_ );
return 0;
}
CFRelease( name );

CoreMidiClientSingleton = client;
}

return CoreMidiClientSingleton;
}

void MidiApi::setCoreMidiClientSingleton(MIDIClientRef client){
CoreMidiClientSingleton = client;
}

void MidiApi::disposeCoreMidiClientSingleton(){
MIDIClientDispose( CoreMidiClientSingleton );
CoreMidiClientSingleton = 0;
}

//*********************************************************************//
// API: OS-X
// Class Definitions: MidiInCore
Expand Down Expand Up @@ -899,32 +934,21 @@ MidiInCore :: ~MidiInCore( void )

// Cleanup.
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
MIDIClientDispose( data->client );
if ( data->endpoint ) MIDIEndpointDispose( data->endpoint );
delete data;
}

void MidiInCore :: initialize( const std::string& clientName )
{
// Set up our client.
MIDIClientRef client;
CFStringRef name = CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII );
OSStatus result = MIDIClientCreate(name, NULL, NULL, &client );
if ( result != noErr ) {
std::ostringstream ost;
ost << "MidiInCore::initialize: error creating OS-X MIDI client object (" << result << ").";
errorString_ = ost.str();
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
}
MIDIClientRef client = getCoreMidiClientSingleton(clientName);

// Save our api-specific connection information.
CoreMidiData *data = (CoreMidiData *) new CoreMidiData;
data->client = client;
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 @@ -960,7 +984,6 @@ void MidiInCore :: openPort( unsigned int portNumber, const std::string &portNam
CFRelease( portNameRef );

if ( result != noErr ) {
MIDIClientDispose( data->client );
errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port.";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
Expand All @@ -970,7 +993,6 @@ void MidiInCore :: openPort( unsigned int portNumber, const std::string &portNam
MIDIEndpointRef endpoint = MIDIGetSource( portNumber );
if ( endpoint == 0 ) {
MIDIPortDispose( port );
MIDIClientDispose( data->client );
errorString_ = "MidiInCore::openPort: error getting MIDI input source reference.";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
Expand All @@ -980,7 +1002,6 @@ void MidiInCore :: openPort( unsigned int portNumber, const std::string &portNam
result = MIDIPortConnectSource( port, endpoint, NULL );
if ( result != noErr ) {
MIDIPortDispose( port );
MIDIClientDispose( data->client );
errorString_ = "MidiInCore::openPort: error connecting OS-X MIDI input port.";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
Expand Down Expand Up @@ -1223,31 +1244,20 @@ MidiOutCore :: ~MidiOutCore( void )

// Cleanup.
CoreMidiData *data = static_cast<CoreMidiData *> (apiData_);
MIDIClientDispose( data->client );
if ( data->endpoint ) MIDIEndpointDispose( data->endpoint );
delete data;
}

void MidiOutCore :: initialize( const std::string& clientName )
{
// Set up our client.
MIDIClientRef client;
CFStringRef name = CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII );
OSStatus result = MIDIClientCreate(name, NULL, NULL, &client );
if ( result != noErr ) {
std::ostringstream ost;
ost << "MidiInCore::initialize: error creating OS-X MIDI client object (" << result << ").";
errorString_ = ost.str();
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
}
MIDIClientRef client = getCoreMidiClientSingleton(clientName);

// Save our api-specific connection information.
CoreMidiData *data = (CoreMidiData *) new CoreMidiData;
data->client = client;
data->endpoint = 0;
apiData_ = (void *) data;
CFRelease( name );
}

unsigned int MidiOutCore :: getPortCount()
Expand Down Expand Up @@ -1310,7 +1320,6 @@ void MidiOutCore :: openPort( unsigned int portNumber, const std::string &portNa
OSStatus result = MIDIOutputPortCreate( data->client, portNameRef, &port );
CFRelease( portNameRef );
if ( result != noErr ) {
MIDIClientDispose( data->client );
errorString_ = "MidiOutCore::openPort: error creating OS-X MIDI output port.";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
Expand All @@ -1320,7 +1329,6 @@ void MidiOutCore :: openPort( unsigned int portNumber, const std::string &portNa
MIDIEndpointRef destination = MIDIGetDestination( portNumber );
if ( destination == 0 ) {
MIDIPortDispose( port );
MIDIClientDispose( data->client );
errorString_ = "MidiOutCore::openPort: error getting MIDI output destination reference.";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
Expand Down
20 changes: 20 additions & 0 deletions RtMidi.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@
#include <string>
#include <vector>


#if defined(__MACOSX_CORE__)

#include <CoreMIDI/CoreMIDI.h>

#endif /* __MACOSX_CORE__ */

/************************************************************************/
/*! \class RtMidiError
\brief Exception handling class for RtMidi.
Expand Down Expand Up @@ -523,6 +530,19 @@ class RTMIDI_DLL_PUBLIC MidiApi
RtMidiErrorCallback errorCallback_;
bool firstErrorOccurred_;
void *errorCallbackUserData_;

#if defined(__MACOSX_CORE__)

protected:
static MIDIClientRef CoreMidiClientSingleton;
MIDIClientRef getCoreMidiClientSingleton(const std::string& clientName) throw();

public:
static void setCoreMidiClientSingleton(MIDIClientRef client);
static void disposeCoreMidiClientSingleton();

#endif /* __MACOSX_CORE__ */

};

class RTMIDI_DLL_PUBLIC MidiInApi : public MidiApi
Expand Down

0 comments on commit 825c5a4

Please sign in to comment.