1212
1313extern void SendPacket (Midi midi , unsigned char c1 , unsigned char c2 , unsigned char c3 );
1414
15- Midi_device_endpoints find_device_endpoints (const char * device );
16- char * CFStringToUTF8 (CFStringRef aString );
17-
1815// Midi represents a MIDI connection that uses the ALSA RawMidi API.
1916struct Midi {
2017 MIDIClientRef client ;
@@ -26,19 +23,14 @@ struct Midi {
2623
2724// Midi_open opens a MIDI connection to the specified device.
2825// If there is an error it returns NULL.
29- Midi_open_result Midi_open (const char * name ) {
30- Midi midi ;
31- OSStatus rc ;
26+ Midi_open_result Midi_open (MIDIEndpointRef input , MIDIEndpointRef output ) {
27+ Midi midi ;
28+ OSStatus rc ;
3229
3330 NEW (midi );
3431
35- // Read input and output endpoints.
36- Midi_device_endpoints device_endpoints = find_device_endpoints (name );
37- if (device_endpoints .error != 0 ) {
38- return (Midi_open_result ) { .midi = NULL , .error = device_endpoints .error };
39- }
40- midi -> input = device_endpoints .input ;
41- midi -> output = device_endpoints .output ;
32+ midi -> input = input ;
33+ midi -> output = output ;
4234
4335 rc = MIDIClientCreate (CFSTR ("scgolang" ), NULL , NULL , & midi -> client );
4436 if (rc != 0 ) {
@@ -52,7 +44,7 @@ Midi_open_result Midi_open(const char *name) {
5244 if (rc != 0 ) {
5345 return (Midi_open_result ) { .midi = NULL , .error = rc };
5446 }
55- rc = MIDIPortConnectSource (midi -> inputPort , midi -> input , midi );
47+ rc = MIDIPortConnectSource (midi -> inputPort , input , midi );
5648 if (rc != 0 ) {
5749 return (Midi_open_result ) { .midi = NULL , .error = rc };
5850 }
@@ -102,63 +94,34 @@ Midi_write_result Midi_write(Midi midi, const char *buffer, size_t buffer_size)
10294int Midi_close (Midi midi ) {
10395 assert (midi );
10496
105- OSStatus rc1 , rc2 , rc3 ;
97+ OSStatus rc1 , rc2 , rc3 , rc4 , rc5 ;
10698
10799 rc1 = MIDIPortDispose (midi -> inputPort );
108100 rc2 = MIDIPortDispose (midi -> outputPort );
109101 rc3 = MIDIClientDispose (midi -> client );
102+ rc4 = MIDIEndpointDispose (midi -> input );
103+ rc5 = MIDIEndpointDispose (midi -> output );
104+
105+ FREE (midi );
110106
111107 if (rc1 != 0 ) return rc1 ;
112108 else if (rc2 != 0 ) return rc2 ;
113109 else if (rc3 != 0 ) return rc3 ;
110+ else if (rc4 != 0 ) return rc4 ;
111+ else if (rc5 != 0 ) return rc5 ;
114112 else return 0 ;
115113}
116114
117- Midi_device_endpoints find_device_endpoints (const char * name ) {
118- ItemCount numDevices = MIDIGetNumberOfDevices ();
119- OSStatus rc ;
120-
121- for (int i = 0 ; i < numDevices ; i ++ ) {
122- CFStringRef deviceName ;
123- MIDIDeviceRef deviceRef = MIDIGetDevice (i );
124-
125- rc = MIDIObjectGetStringProperty (deviceRef , kMIDIPropertyName , & deviceName );
126- if (rc != 0 ) {
127- return (Midi_device_endpoints ) { .device = 0 , .input = 0 , .output = 0 , .error = rc };
128- }
129- if (strcmp (CFStringToUTF8 (deviceName ), name ) != 0 ) {
130- continue ;
131- }
132- ItemCount numEntities = MIDIDeviceGetNumberOfEntities (deviceRef );
133-
134- for (int i = 0 ; i < numEntities ; i ++ ) {
135- MIDIEntityRef entityRef = MIDIDeviceGetEntity (deviceRef , i );
136- ItemCount numDestinations = MIDIGetNumberOfDestinations (entityRef );
137- ItemCount numSources = MIDIGetNumberOfSources (entityRef );
138-
139- if (numDestinations < 1 || numSources < 1 ) {
140- continue ;
141- }
142- MIDIEndpointRef input = MIDIGetSource (0 );
143- MIDIEndpointRef output = MIDIGetDestination (0 );
144-
145- return (Midi_device_endpoints ) { .device = deviceRef , .input = input , .output = output , .error = 0 };
146- }
147- }
148- return (Midi_device_endpoints ) { .device = 0 , .input = 0 , .output = 0 , .error = -10901 };
149- }
150-
115+ // CFStringToUTF8 converts a CoreFoundation string to a UTF-encoded C string.
116+ // Callers are responsible for free'ing the returned string.
151117char * CFStringToUTF8 (CFStringRef aString ) {
152118 if (aString == NULL ) {
153119 return NULL ;
154120 }
155-
156- CFIndex length = CFStringGetLength (aString );
157- CFIndex maxSize =
158- CFStringGetMaximumSizeForEncoding (length , kCFStringEncodingUTF8 ) + 1 ;
159- char * buffer = (char * )malloc (maxSize );
160- if (CFStringGetCString (aString , buffer , maxSize ,
161- kCFStringEncodingUTF8 )) {
121+ CFIndex length = CFStringGetLength (aString );
122+ CFIndex maxSize = CFStringGetMaximumSizeForEncoding (length , kCFStringEncodingUTF8 ) + 1 ;
123+ char * buffer = (char * )malloc (maxSize );
124+ if (CFStringGetCString (aString , buffer , maxSize , kCFStringEncodingUTF8 )) {
162125 return buffer ;
163126 }
164127 free (buffer ); // If we failed
0 commit comments