Advice on midi controller patch for Mackie C4
Hi,
As my (relatively) first learning project patching Max, I made a "midi feedback device" for my Mackie C4 controller. The C4 has 32 "push button encoders" with led ring and lcd screen feedback and 19 "buttons" 7 of which have associated feedback leds. The patch in this project handles tracking four "pages" of encoder "fader" data (128 virtual encoders) in two states, "pressed" and "released", as well as button led status. The patch works correctly as far as I know, but could be better engineered I'm sure. Specifically, I used four named Dict objects as the main data structure(s) in the patch, but that approach doesn't necessarily seem easily scalable or customizable. It seems like there should be an easier more idiomatically Max way to (possibly restructure and) continue adding functionality.
Going forward I'm picturing this patch (or some evolutionary step beyond) as a kind of C4 "hardware companion" abstraction I can use freely in any other jitter or gen based, for example, patches I build in the future. To get there it seems like I will want a way to easily customize the behavior of individual encoders and/or buttons in any given other patch. For example, the C4 encoders understand five styles of led ring feedback data and currently the patch only implements a single global ring feedback style selector. But as an abstraction in other patches, I would like to be able to easily assign a custom ring feedback style to each (virtual) encoder rather than using just one global ring feedback style for all encoders. Similarly, I would like to give each encoder a custom "lcd display name" specific to its role in whatever other patch the abstraction gets used rather than the numeric ID key currently displayed (0 - 127). and on, and on... Thoughts?
I'd also like to learn the a standard idiomatic way to connect "dials and sliders" in other patches to the (currently) Dict data structures in this project (to control by C4 encoders). Do the Inspector's "Parameter" checkboxes relate to that kind of functionality?
I already use a custom C4 "remote script" for Live and m4l where such dial and slider connections come with the territory. This patch is (currently?) about working "only" in Max.
Hi again, I think I finally tracked down enough clues to figure out exactly what problem I would like some help with in the previously attached project zip. I've thought I've solved the issue so many times, only to see it continue to reoccur time after time.
The attached image shows the entire issue. You can also refer to the "main" patcher in the previously attached project.
The bytes in the midi messages going past Watchpoints 1, 3, and 4 are getting (randomly?) "laced" going through the midiout object(s) down the midi wire to the device destroying the integrity of random? midi messages received by the device; but only when the Max debugger is disabled. That's part of why the issue has been difficult to isolate and identify, "debugging" only shows the problem in relief, by what isn't happening.
I've already tried several less than satisfactory ways to remedy the issue using Max objects like, for example, zl.queue and coll, without any more than partial success. So my question is, how can I replicate (just enough of) what the debug-enabled-Watchpoints do in the patch using Max objects instead of Watchpoints? (So this patch works correctly because midi message "integrity" remains valid on the wire even when Max debugging is disabled.)
The Watchpoints view attached shows the "feedback" messages resulting from a single physical (C4 Split) button press (and release). wp1 logged the 3 "actual button press-and-release" feedback note messages, while wp3 logged 32 calculated cc feedback messages, and wp4 logged 4 calculated sysex feedback messages. (wp1 shows a message count of 3 (not 2) because of troubleshooting efforts. I changed the patch to also send a single "three way hammer" message to all 3 of the LEDs controlled by the single (Split) button, but the byte-lacing problem persists (because it's not a nail)).
When debugging is disabled, the bytes coming out of this patch going down the midi wire to the device are (randomly?) reordered creating often-invalid midi messages in a way that is somehow completely resolved and does not exist when Watchpoints-only-debugging is enabled. When debugging is enabled (no breakpoints), all the bytes going down the wire to the device remain "delaced" and in correct, intended "serial midi messages" order.
Once again, how can I replicate what the debug-enabled-Watchpoints do in the patch using "real" Max objects instead of Watchpoints? (So this patch also works correctly when debugging is disabled because midi message "integrity" on the wire still remains valid.)
Thanks, J
A guess would be to use defer objects where you have watchpoints. You're dealing with high priority input from the midiin.
Thanks! Your guess put me on the path to what seems to be a solution that will "survive". I started seeing 476 (I assume) "extra argument with message int" errors in the console from the "midiout" object as soon as I implemented and tested what you suggested.
It turns out (it appears) I only needed to "deferlow" the sysex messages going through wp4 in the image above which shows the "byte sized" message watch count of 476. That high count is because I had previously introduced a "manual" 2 sample delay on each of those 476 bytes (in four 119 byte sysex messages) sent down the wire because the C4 (apparently) can't handle 476 bytes of (LCD display text) midi data "all at once" without exhibiting weird seemingly random buffering behavior. I used "deferlow" just before the "queue unrolling" code where the 2 sample delay loop empties the "queue" of sysex message data and deferring that whole "unrolling operation" to the tail of Max's "low priority queue" seems to have resolved the "midi message byte lacing" issue I asked for help with.
Thanks again, J