We connected a Korg Keystage and an opsix module to a Mac by USB, routed them to each other in MIDIFabric, and MIDI-CI Property Exchange would not work.
We believe it has to do with macOS itself exchanging MIDI-CI messages with USB devices and relaying some of them between devices. When a device receives the same message both from macOS and through the routing, it treats the reply as a conflict, and Property Exchange fails, or stops working after you power-cycle one of the devices. We have not confirmed the exact cause. Connecting the two devices directly with MIDI (DIN) cables worked.
How we noticed
In a MIDI monitor, the device we had power-cycled kept sending MIDI-CI Discovery about every 100 ms, and each time the other device answered with “Invalidate MUID”. A connection that had worked once never came back after the power cycle.
To find out whether MIDIFabric’s routing was to blame, we stopped MIDIFabric and watched with only a MIDI monitor running. That showed us that macOS itself takes part in MIDI-CI and relays messages between the devices.
What you might see
- A controller does not show the parameter names of a synth that supports Property Exchange.
- It worked once, but after you power-cycled one device it never connects again.
- A MIDI monitor shows the same MIDI-CI Discovery messages repeating about every 100 ms, each followed by “Invalidate MUID”.
What macOS does with MIDI-CI
These are things we confirmed with a MIDI monitor, with no routing app running:
- macOS takes part in MIDI-CI itself. MIDIServer sends its own Discovery to USB devices, with a new MUID each time it starts, and asks them for Property Exchange information (PE Capabilities and the ResourceList). Apple’s CoreMIDI documentation says the MIDI server runs MIDI-CI discovery automatically for UMP endpoints and MIDI 1.0 devices.
- macOS relays some broadcast MIDI-CI messages between devices. A Discovery that the opsix module sent to all devices was delivered to the Keystage by MIDIServer itself. We saw this in the opsix → Keystage direction only, not the other way. Messages addressed to one specific device were usually not relayed, but we cannot rule it out.
- The number of relays changes. Right after MIDIServer started, the message was relayed once. On another day we saw three. After the devices had repeatedly reconnected, one message from the opsix module made the Keystage reply hundreds of times.
Why routing makes it worse
MIDI-CI needs both directions, so a routing app has to carry the messages between the two devices. When macOS also relays a broadcast message, the receiving device gets it twice, once from macOS and once from the routing app, and replies twice. The other device sees two replies from the same MUID, treats it as a conflict, and invalidates that MUID. Property Exchange then fails, and after a power cycle the devices can fall into a loop of Discovery, reply and Invalidate MUID.
The device side may also play a part: we saw a device invalidate the new MUID of a device it had seen before. We have not separated these causes.
An app cannot fix this by itself. macOS offers no public setting to stop its own MIDI-CI discovery or relaying (MIDICIDeviceManager only reports discovered devices). In MIDIFabric we tried removing duplicate MIDI-CI messages along the route, but the direction and number of relays were not constant, and it also removed duplicates the devices sent on purpose, so we did not adopt it.
What you can do
- Connect the two devices directly with MIDI (DIN) cables for MIDI-CI between them. In our test, MIDI-CI worked this way as long as the device we power-cycled was not connected to the Mac by USB.
- Reset the state when it gets stuck. Quit every app that uses MIDI so that MIDIServer quits, then power-cycle the devices.
- Block SysEx on routes that do not need MIDI-CI. If you only need notes and controllers between the devices, filter out SysEx on that route. MIDI-CI messages are SysEx, so this stops the loop, but Property Exchange will not work over that route.
We will update this page if we learn more.
About MIDIFabric
MIDIFabric forwards MIDI-CI unchanged, and its monitor shows MIDI-CI messages by name. The relaying described above is done by macOS and also happens without MIDIFabric.