@@ -2,20 +2,17 @@ package dev.atsushieno.ktmidi
2
2
3
3
import kotlinx.cinterop.*
4
4
import platform.CoreFoundation.CFStringRef
5
- import platform.CoreFoundation.CFStringRefVar
6
5
import platform.CoreMIDI.*
7
- import platform.Foundation.CFBridgingRelease
8
- import platform.Foundation.CFBridgingRetain
9
6
import platform.darwin.SInt32Var
10
7
import platform.posix.alloca
11
8
12
9
class CoreMidiAccess : MidiAccess () {
13
10
override val name = " CoreMIDI"
14
11
override val inputs: Iterable <MidiPortDetails >
15
- get() = (0UL until MIDIGetNumberOfSources ()).map { CoreMidiPortDetails ( MIDIGetSource (it)) }
12
+ get() = (0UL until MIDIGetNumberOfSources ()).map { MIDIGetSource (it) }.filter { it != 0u }.map { CoreMidiPortDetails (it ) }
16
13
17
14
override val outputs: Iterable <MidiPortDetails >
18
- get() = (0UL until MIDIGetNumberOfDestinations ()).map { CoreMidiPortDetails ( MIDIGetDestination (it)) }
15
+ get() = (0UL until MIDIGetNumberOfDestinations ()).map { MIDIGetDestination (it) }.filter { it != 0u }.map { CoreMidiPortDetails (it ) }
19
16
20
17
override suspend fun openInput (portId : String ): MidiInput = CoreMidiInput (inputs.first { it.id == portId } as CoreMidiPortDetails )
21
18
@@ -26,15 +23,16 @@ private class CoreMidiPortDetails(val endpoint: MIDIEndpointRef)
26
23
: MidiPortDetails {
27
24
28
25
@OptIn(ExperimentalForeignApi ::class )
29
- override val id: String = getPropertyString(kMIDIPropertyUniqueID) ? : endpoint.toInt().toString()
26
+ override val id: String
27
+ get() = getPropertyInt(kMIDIPropertyUniqueID).toString()
30
28
31
29
@OptIn(ExperimentalForeignApi ::class )
32
30
private fun getPropertyString (property : CFStringRef ? ): String? = memScoped {
33
- viaPtr { str ->
31
+ viaPtr< CFStringRef > { str ->
34
32
val status = MIDIObjectGetStringProperty (endpoint, property, str)
35
33
if (status == 0 || str.rawValue == NativePtr .NULL )
36
34
return @memScoped null
37
- }?.getString ()
35
+ }?.releaseString ()
38
36
}
39
37
40
38
@OptIn(ExperimentalForeignApi ::class )
@@ -47,13 +45,17 @@ private class CoreMidiPortDetails(val endpoint: MIDIEndpointRef)
47
45
}
48
46
49
47
@OptIn(ExperimentalForeignApi ::class )
50
- override val manufacturer = getPropertyString(kMIDIPropertyManufacturer)
48
+ override val manufacturer
49
+ get() = getPropertyString(kMIDIPropertyManufacturer)
51
50
@OptIn(ExperimentalForeignApi ::class )
52
- override val name = getPropertyString(kMIDIPropertyDisplayName) ? : getPropertyString(kMIDIPropertyName) ? : " (unnamed port)"
51
+ override val name
52
+ get() = getPropertyString(kMIDIPropertyDisplayName) ? : getPropertyString(kMIDIPropertyName) ? : " (unnamed port)"
53
53
@OptIn(ExperimentalForeignApi ::class )
54
- override val version = getPropertyString(kMIDIPropertyDriverVersion)
54
+ override val version
55
+ get() = getPropertyString(kMIDIPropertyDriverVersion)
55
56
@OptIn(ExperimentalForeignApi ::class )
56
- override val midiTransportProtocol = getPropertyInt(kMIDIPropertyProtocolID)
57
+ override val midiTransportProtocol
58
+ get() = getPropertyInt(kMIDIPropertyProtocolID)
57
59
}
58
60
59
61
private abstract class CoreMidiPort (override val details : CoreMidiPortDetails ) : MidiPort {
@@ -85,16 +87,11 @@ private class CoreMidiInput(details: CoreMidiPortDetails) : CoreMidiPort(details
85
87
init {
86
88
memScoped {
87
89
val clientName = " KTMidiInputClient"
88
- clientName.usePinned { clientNameBuf ->
89
- val clientPtr = alloc<MIDIClientRefVar >()
90
- MIDIClientCreate (clientNameBuf.addressOf(0 ).reinterpret(), null , null , clientPtr.reinterpret())
91
- client = clientPtr.value
92
-
90
+ client = viaPtr { clientPtr: CPointer <MIDIClientRefVar > ->
91
+ MIDIClientCreate (clientName.toCFStringRef(), null , null , clientPtr)
93
92
val portName = " KTMidiInputPort"
94
- portName.usePinned { portNameBuf ->
95
- val portPtr = alloc<MIDIPortRefVar >()
96
- MIDIInputPortCreate (client, portNameBuf.addressOf(0 ).reinterpret(), null , null , portPtr.reinterpret())
97
- port = portPtr.value
93
+ port = viaPtr { portPtr: CPointer <MIDIPortRefVar > ->
94
+ MIDIInputPortCreate (client, portName.toCFStringRef(), null , null , portPtr)
98
95
}
99
96
}
100
97
}
@@ -121,17 +118,12 @@ private class CoreMidiOutput(details: CoreMidiPortDetails) : CoreMidiPort(detail
121
118
122
119
init {
123
120
memScoped {
124
- val clientName = " KTMidiInputClient"
125
- clientName.usePinned { clientNameBuf ->
126
- val clientPtr = alloc<MIDIClientRefVar >()
127
- MIDIClientCreate (clientNameBuf.addressOf(0 ).reinterpret(), null , null , clientPtr.reinterpret())
128
- client = clientPtr.value
129
-
130
- val portName = " KTMidiInputPort"
131
- portName.usePinned { portNameBuf ->
132
- val portPtr = alloc<MIDIPortRefVar >()
133
- MIDIInputPortCreate (client, portNameBuf.addressOf(0 ).reinterpret(), null , null , portPtr.reinterpret())
134
- port = portPtr.value
121
+ val clientName = " KTMidiOutputClient"
122
+ client = viaPtr { clientPtr: CPointer <MIDIClientRefVar > ->
123
+ MIDIClientCreate (clientName.toCFStringRef(), null , null , clientPtr)
124
+ val portName = " KTMidiOutputPort"
125
+ port = viaPtr { portPtr: CPointer <MIDIPortRefVar > ->
126
+ MIDIOutputPortCreate (client, portName.toCFStringRef(), portPtr)
135
127
}
136
128
}
137
129
}
0 commit comments