I've been building a USB MIDI 2.0 8-port DIN interface on an RP2040 and have gotten it enumerating correctly on Linux (kernel 6.17) as a UMP Streaming device (ALSA leaves the JR clock handling to the application). On macOS (Tahoe) isn't CoreMidi supposed to handle the JR timestamps/clocks?
The device: A translator/interface - USB MIDI 2.0 on one side, 8 physical DIN MIDI 1.0 ports on the other. The DIN ports carry MIDI 1.0 content, so the Function Block midiProtocol is correctly set to 0x01.
What works on macOS: After several rounds of descriptor fixes (IAD triplet, CS_INTERFACE GTB type, MS Header in alt-0, UAC 1.0 AC header format), AppleMIDIUSBDriver binds correctly and MIDIServer enumerates the device as a UMP device. MIDIServer logs confirm it reads gtb.midiProtocol=0x2 from the inline GTBs in alt-1. UMP Endpoint Discovery completes successfully.
The problem: macOS only ever negotiates MIDI-1UP - it sends a Stream Config Request with protocol=0x01 and does not accept counter-proposals for protocol=0x02. The device appears in CoreMIDI as a standard MIDI 1.0 device. JR Timestamps/clocks are never send from the host.
What I've tried:
Setting bMIDIProtocol=0x02 in inline GTB descriptors (macOS reads it correctly but still negotiates 0x01)
Announcing midi1=true, midi2=true in Endpoint Info (no change)
Announcing midi1=false, midi2=true (device disappears from CoreMIDI - macOS apparently requires midi1 support)
Counter-proposing protocol=0x02 in Stream Config Notification (macOS ignores it and resends the 0x01 request)
The conclusion from MIDIServer logs is that configureDeviceUsingPortMap makes a hardcoded decision - seemingly based on the Function Block midiProtocol field - regardless of what the Endpoint Info capability flags say.
The question:
Are JR Timestamps ever achievable on macOS for a translator device whose function blocks report midiProtocol=0x01? Or does macOS require midiProtocol=0x02 function blocks to offer MIDI-2UP negotiation?
If a device sets midiProtocol=0x02 on its function blocks (meaning it would present the DIN ports to the host as MIDI 2.0 channels), does macOS then negotiate MIDI-2UP and honour JR Timestamps?
Is there any MIDI-CI or UMP Stream exchange that can prompt macOS to switch to MIDI-2UP after initial enumeration?
And what is up with the phantom Midi 2 device with 0 ins/outs ?
Any insight from people who have shipped MIDI 2.0 devices that work under CoreMIDI would be very welcome.
Ok there is a bit to unpack here. If I understand correctly, you want to run 8 MIDI 1.0 DIN ports over a UMP (USB MIDI 2.0) device - and send JR Timestamp messages? Or Receive JR Timestamp? I don't believe any of the OS currently doing anything with JR Timestampls except pass them on - but more on that later...
I am going to make some suggestions - excuse me if I suggest things you have already done.
Setting aside the JR Timestamp issue. If you want CoreMIDI to work better (in your use case) you are better off using Group Terminal Blocks. I would suggest one GTB for MIDI 1.0 pair. eg. DIN 1 I/O on Group 0, DIN 2 on Group 1 etc. Set the bMIDIProtocol in the USB descriptor to 0x03 - this declares MIDI 1.0, but still accept 128bit messages. There is no need to upscale the messages from MT2 (MIDI 1.0 CVM) to MT4 (MIDI 2.0 CVM) - it will provide no benefit, and can in some case cause issues.
Still report the Endpoint, and FB stream messages matching the GTB settings.
This means that the DIN ports will appear as MIDI 1.0 src/dest in Mac, while the "MIDI 2.0" src dest will recieve all messages JR Messages (and all the MT2 messages from the other Groups)
What MacOS are you aiming for? - earlier versions do some strange things with mixing MIDI 1.0 and MIDI 2.0 protocols.
Thanks for the reply 🙂
I'm on Tahoe
Your proposal was what I had first, but seeing no JR clocks (but UMP messages), I was chasing getting the the MIDIServer to add the FBs to the "Midi 2 0 ins/ 0 outs " 'block' in the belief that JR Clock would be sent by the CoreMIDI.
So I guess ALSA is on par in terms of JR - i.e. leave it all to the applications, and no automatically mapping of CoreMIDI timestamps to/from the UMP JR time domain.
MacOS also insist on making each FB appears as Block <N>, and not with the names i set in the descriptors. ALSA picks up my custom names just fine.
Found my bug with the group names 🙂
Yep JR Timestamp is not built into the OS's (yet). There is a bit of discussion around that in the various companies. I would suggest that if you want JR Timestamps added then please create a Feedback Request on MacOS, and talk about it on the Microsoft Discord. That's how these companies know there is a need 🙂
But it sounds like the naming problem is solved - so that is great 🙂
This is a really interesting thread — the JR Timestamp issue is one I've been following as someone working on audio-to-MIDI transcription tools.
Timing precision is critical in our domain too. When converting audio recordings to MIDI, the accuracy of detected note onsets and offsets directly affects how usable the resulting MIDI file is in a DAW. Right now we output standard Type 1 MIDI files (which most users still need for compatibility), but as MIDI 2.0 adoption grows, having JR Timestamp support at the OS level would open up possibilities for much tighter timing resolution in transcribed MIDI data.
It's frustrating to hear that macOS essentially hardcodes the protocol negotiation based on Function Block midiProtocol. Seems like a case where the spec allows flexibility but the implementation doesn't follow through yet.
Andrew's suggestion to use bMIDIProtocol=0x03 for the GTBs sounds like the right pragmatic workaround for now. Curious whether you've seen any timing drift with that approach compared to native MIDI 2.0 negotiation on Linux?
For anyone interested in the audio-to-MIDI side of things, I've been building a tool at removed link (
removed link handles the transcription part — would love to eventually support MIDI 2.0 output with proper JR timing once OS support catches up.