I can send MIDI note data to midi destination ports derived from MIDIGetDestination, but when I use MIDISourceCreateWithProtocol no note data seems to be sent, although I can select the virtual port in an external application:
let midiEndpointRef_bus1: MIDIEndpointRef
let midiEndpointRef_bus2: MIDIEndpointRef
var virtualEndpoint1: MIDIEndpointRef
var virtualEndpoint2: MIDIEndpointRef
var midiClientRef1: MIDIClientRef = 0
MIDIClientCreate("client1" as CFString,nil,nil, &midiClientRef1)
var midiOutputPortRef: MIDIPortRef = 0
MIDIOutputPortCreate(midiClientRef1,"ouputPort" as CFString, &midiOutputPortRef)
let destinationNames = Self.midiDestinationNames()
guard
let iac_bus1 = destinationNames.firstIndex(of: "IAC Driver Bus 1"),
let iac_bus2 = destinationNames.firstIndex(of: "IAC Driver Bus 2")
else {
return nil
}
midiEndpointRef_bus1 = MIDIGetDestination(iac_bus1)
midiEndpointRef_bus2 = MIDIGetDestination(iac_bus2)
// Create virtual MIDI
virtualEndpoint1 = 0
virtualEndpoint2 = 0
if #available(macOS 11.0, *) {
MIDISourceCreateWithProtocol(midiClientRef1, "Port A" as CFString, ._2_0, &virtualEndpoint1)
MIDISourceCreateWithProtocol(midiClientRef1, "Port B" as CFString, ._2_0, &virtualEndpoint2)
} else { print("ERROR: FAILED TO CREATE VIRTUAL MIDI SOURCE") }
//this works
// midiMessenger = MidiMessageSender(
// midiOutputPortRef: midiOutputPortRef,
// destinationEndpointRef_1: midiEndpointRef_bus1,
// destinationEndpointRef_2: midiEndpointRef_bus2
// )
//this doesn't
midiMessenger = MidiMessageSender(
midiOutputPortRef: midiOutputPortRef,
destinationEndpointRef_1: virtualEndpoint1,
destinationEndpointRef_2: virtualEndpoint2
)
What am I missing?
[Edit: here is the MidiMessenger class]
public class MidiMessageSender: MidiDeviceService {
var midiOutputPortRef: MIDIPortRef
let destinationEndpointRef_1: MIDIEndpointRef
let destinationEndpointRef_2: MIDIEndpointRef
public init(
midiOutputPortRef: MIDIPortRef,
destinationEndpointRef_1: MIDIEndpointRef,
destinationEndpointRef_2: MIDIEndpointRef
) {
self.midiOutputPortRef = midiOutputPortRef
self.destinationEndpointRef_1 = destinationEndpointRef_1
self.destinationEndpointRef_2 = destinationEndpointRef_2
}
public func sendNoteMidiMessage(
channel: UInt8,
noteNumber: UInt8,
velocity: UInt8,
timestamp: MIDITimeStamp
) {
let endpoint = channel / 16
let ch = channel % 16
let selectedDestinationEndpointRef = endpoint == 0
? destinationEndpointRef_1
: destinationEndpointRef_2
let status = velocity == 0 ? .noteOff + ch : .noteOn + ch
var midiPacket = MIDIPacket()
var packetList = MIDIPacketList()
midiPacket.length = 3
midiPacket.timeStamp = timestamp
midiPacket.data.0 = status
midiPacket.data.1 = noteNumber
midiPacket.data.2 = velocity
packetList = MIDIPacketList(numPackets: 1, packet: midiPacket)
MIDISend(midiOutputPortRef, selectedDestinationEndpointRef, &packetList)
}
}