XCtrl quirks

While working with the XCtrl protocol (and the X-Touch), I found myself throwing shedloads of packets at it whenever any state changed. These packets could be as little as four bytes long (in the case of a meter update). A bit of experimentation though, and it turns out you can chain multiple XCtrl packets into one UDP packet, massively cutting down on the network overhead. We're still bound by UDP limits, but pushing display, meter, fader and button states in one hit seems to behave pretty well!

To set a value for one of the channel meters on the X-Touch, we use the MIDI 'pitch bend' command. Most MIDI packets are one command byte and two data bytes, so my original data structure had everything being a 3-byte layout, with the second data byte just being 0x00 if it wasn't actually in use. For all except the first channel, the meter updates behaved pretty well with this method. But for some reason, the first channel refuses to update if you send a second data byte at all. Tracking this down was fun, I managed to spend far too long digging around in the data parsers before just trying to send the packet manually, with and without the second byte. No second byte, it immediately worked and a glorious facepalm moment ensued.

Pulling data from a constant VBAN stream, processing it and pushing those state updates out to the X-Touch seems to be verging on the limits of how fast Ruby can run, so next up will be the fun of translating everything into Rust to kick it up a notch.