I've been working to migrate an older Core MIDI sending implementation to send MIDI 1.0 messages using Apple's newer UMP-aware MIDI Event List API methods.
I've figured out code that runs and should output MIDI clock messages, but when I send it with MIDISendEventList(...)
I see nothing being output from my MIDI interface; there's also no error returned from that method to indicate what the problem is.
Here is the code I'm using:
const ByteCount clockMessageSize = 1;
const UInt32 clockMessage[clockMessageSize] = { (UInt32)0xF8 }; // MIDI clock tick
const MIDITimeStamp timeStamp = mach_absolute_time();
MIDIEventList clockMessageEventList = {};
MIDIEventPacket* clockMessageEventListEndPacket = nullptr;
clockMessageEventListEndPacket = MIDIEventListInit(&clockMessageEventList, kMIDIProtocol_1_0);
clockMessageEventListEndPacket = MIDIEventListAdd(&clockMessageEventList, sizeof(MIDIEventList::packet), clockMessageEventListEndPacket, timeStamp, clockMessageSize, clockMessage);
for (NSUInteger endpointRefIndex = 0; endpointRefIndex < endPointRefsCount; ++endpointRefIndex) {
MIDIObjectRef destinationEndpoint = endPointRefs[endpointRefIndex];
OSStatus midiSendError = MIDISendEventList(outputPortRef, destinationEndpoint, &clockMessageEventList);
if (midiSendError != noErr) {
printf("MIDISendEventList error: %i", (int)midiSendError);
}
}
Inspecting clockMessageEventList.packet
after it has been configured but before it is sent shows:
(248, 0, 0, [... all zeros to index 63])
Does anyone know where I'm going wrong?
With a bit of additional direction provided by https://stackoverflow.com/a/74248460/8653957 I managed to crack this.
For some reason, the word created for the MIDI clock message needs to be formatted slightly differently, with the first byte being 0x10
, and the second byte being the MIDI clock message:
const ByteCount clockMessageSize = 1;
const UInt32 clockMessage[clockMessageSize] = { 0x10000000 | ((UInt32)message << 16) };
const MIDITimeStamp timeStamp = mach_absolute_time();
MIDIEventList clockMessageEventList = {};
MIDIEventPacket* clockMessageEventListEndPacket = nullptr;
clockMessageEventListEndPacket = MIDIEventListInit(&clockMessageEventList, kMIDIProtocol_1_0);
clockMessageEventListEndPacket = MIDIEventListAdd(&clockMessageEventList, sizeof(MIDIEventList::packet), clockMessageEventListEndPacket, timeStamp, clockMessageSize, clockMessage);
If anyone know why this is, please post it! But here you go, MIDI clock via MIDIEventList.