Thank you for the patch! I generally like the approach of filtering out the endpoint when it’s non-functional as it should be in this case. I tried it out today but am still running into the same issue. I studied the execution a bit more to understand what’s happening.
The assertion that gets triggered is inside getSyntheticBlocks():
if (result >= blocks.size())
{
jassertfalse;
return;
}
Just before that, when the function retrieves the number of groups from the endpoint:
const auto bitmap = getUMPActiveGroupBitmap (endpoint);
if (! bitmap.has_value())
return;
const auto numGroups = countNumberOfBits ((uint32) *bitmap);
For all of the device’s normal endpoints, bitmap takes the value (1 << n) where n is the group number for that endpoint, and numGroups correctly comes out as 1. This is all good.
However, when the mysterious “MIDI 2.0” entity is encountered, bitmap returns 15 (0b1111) and numGroups is 4 — suggesting this entity covers groups 1-4. This is surprising because earlier in execution canTransmitGroupless identified the same endpoint as having no groups. The documentation for kMIDIPropertyUMPActiveGroupBitmap states:
Any UMP-native endpoint lacking this property and the subsequently defined property kMIDIPropertyCanTransmitGroupless is assumed to handle/transmit all UMP traffic.
I’m not sure what to make of this, but I would expect the “MIDI 2.0” endpoint to have no active groups given that MIDI Studio shows it with 0 ins / 0 outs. I would expect kMIDIPropertyUMPActiveGroupBitmap to be undefined or set to 0 since kMIDIPropertyCanTransmitGroupless is truth-y. When I use MIDI 2.0 Workbench, all the USB descriptors and function block tables look to be correct for the defined GTBs.
Also an FYI, MIDIUMPEndpointManager.sharedInstance.UMPEndpoints is empty, so bidiUmpEndpoints is also empty and findAllUMPDevices never skips any device. Not sure if this changes things but the device appears this way in MIDI Studio:
- Device
Block 1 (1 in / 1 out)
Block 2 (1 in / 1 out)
Block 3 (1 in / 1 out)
...
Block 16 (1 in / 1 out)
MIDI 2.0 (0 ins / 0 outs)
If the “MIDI 2.0” entity’s group count were reported as 0, the original implementation would work correctly. When I use MIDI 2.0 Workbench, all the USB descriptors and function block definitions look to be correct, so I can’t think of what else might be the issue other than perhaps a bug in CoreMIDI? Unfortunately I don’t have another macOS version available to test against. It seems like the information coming back from CoreMIDI precludes the first two proposed solutions.
The idea about having one GTB covering all 16 groups would actually be the ideal, and its where I started, but for some reason the OS is not propagating the function block names to the DAWs for each group. For example, in Ableton, with that configuration the ports show up as “Device (Port 1)”, “Device (Port 2)”, etc. Providing the names through the USB descriptor resolves this, but it requires 16 GTBs, which is how I got here.
Anecdotally, increasing the blocks array capacities to 34 (in various places) works. I’m not suggesting it’s ideal, based on the spec, but it does resolve this strange edge-case.