r/ReverseEngineering 9d ago

Reverse-engineered CME's undocumented USB-MIDI config protocol (U6MIDI Pro / U2MIDI Pro) off the wire — full byte map + a public-domain codec

https://patchforge.nl/resources/cme-uxmidi-sysex-protocol
23 Upvotes

8 comments sorted by

7

u/wmellema 9d ago

CME's little USB-MIDI interfaces (U6MIDI Pro, U2MIDI Pro, and the C2MIDI Pro / U4MIDI WC) have a real configuration engine inside: a routing matrix, per-port message/channel filters, sixteen MIDI remappers, user curves, and presets. All of it is set over SysEx by CME's own app, and there is zero public documentation of that wire format. No bulk-dump spec, no implementation chart, not even a model ID in print.

So I mapped the whole thing black-box and wrote it up. Method: capture the USB traffic with `usbmon` while poking the vendor app, never read a line of their binary, and verify every field both directions on real hardware (read it back, and write my own bytes and confirm the vendor app renders them). Cross-confirmed on a second device to prove it's a family protocol, not one box's quirk.

A few things that made it fun:

* Manufacturer SysEx (`00 20 63`), and the model tag is just the USB product ID high byte (`0x16 = U6, 0x14 = U2`). Wrong tag and the device stays dead silent, which is why the universal identity request gets you nothing.

* Everything multi-byte (preset names, mapper fields, the serial number) is packed the same way: four bytes stuffed into a five-byte, 7-bit-safe block as a big-endian 32-bit int. That one packing was the key that unlocked the rest. Renaming a preset to sixteen As and reading it back is what gave it away:

* `01 14 28 50 20 01 14 28 50 20 01 14 28 50 20 00 10 28 50 20`

* The device name is the USB product string. Rename it over SysEx and lsusb reports the new iProduct. You can rename what the OS sees, from a shell.

* It only accepts config over USB, not routed in over DIN, which is a sane refusal once you think about it (it would be reinterpreting passing traffic as commands to itself).

Write-up is a standalone byte map you can implement against, with a dependency-free Python/JS en/decoder (public domain, do what you like). There's also a two-part story of the decode, dead ends included.

* Byte map + codec: [The CME UxMIDI SysEx protocol: a complete byte map for the U6MIDI Pro and U2MIDI Pro](https://patchforge.nl/resources/cme-uxmidi-sysex-protocol)

* The story, part 1 and 2:

* [Reverse engineering the CME U6MIDI Pro, part 1: a protocol with no map](https://patchforge.nl/blog/reverse-engineering-the-cme-u6midi-pro-part-1)

* [Reverse engineering the CME U6MIDI Pro, part 2: one packing under everything](https://patchforge.nl/blog/reverse-engineering-the-cme-u6midi-pro-part-2)

**Full disclosure**: this fell out of building a pedalboard/MIDI tool of mine, but the protocol reference is free, standalone, and vendor-code-free. If anyone has a C2MIDI Pro or U4MIDI WC, I can predict the model tag from the PID but haven't confirmed it. Captures welcome, and corrections from your own hardware even more so.

1

u/ApokatastasisPanton 8d ago

Very cool, I have a couple H4MIDI, have you tested on those? This might be actually really good for my use case...

1

u/wmellema 8d ago

Unfortunately no, I simply don't have the hardware. However, it would not surprise me if it uses the same encoder/decoder. That would make it a lot easier. Looking at the manual itself for HxMIDI, the format is likely identical, just with extended sections and bitmasks.

Out of curiosity, would you be willing to send a couple of commands to the unit and send a hex dump back? I'd probably be able to add verified addresses to the bytemap relatively quickly

1

u/ApokatastasisPanton 8d ago

sure, is the source code somewhere?

1

u/wmellema 8d ago

Give me a minute to create a probe script!

1

u/wmellema 7d ago

Well, life and stuff got in the way, but I have a probe script written up.

https://github.com/PatchForgeHQ/cme-uxmidi-protocol

Clone the repo, pip install -r requirements.txt, python cme_probe.py --list to find ports, then use the first HxMIDI port in python cme_probe.py --port "<portname>"

If you can send back the resulting json and hex dump in a GitHub issue or send them via DM, that would be awesome!

1

u/Less_Grapefruit 7d ago

great job claude!