Make MackieBackend an adapter over the shared C translator - #6
Merged
Conversation
The Mackie Control translation existed twice: once in MackieBackend for the host bridge, once in src/mcu/c8_mcu.c for the dongle firmware. Two copies of a protocol mapping drift, and they drift silently -- each stays correct against its own tests while producing different bytes on the wire. MackieBackend now owns no translation logic at all. It holds a c8_mcu_t, feeds surface input into it and routes its two output callbacks to the MCU port and to the surface. The MCU note map, the Bank/Nudge/Zoom nav group, the LCD SysEx parser, the V-pot ring and meter encoding and the selected- track set all come out: 213 lines deleted against 290 added, and most of what is added is the test. The C module is the one that survives because it is the tested one, and because the firmware compiles that exact file rather than a copy. Two consequences worth being explicit about. Feedback gains raw(), a passthrough for back-ends that emit device bytes themselves. The translator already produces Command|8 wire format, so routing its output through the named encoders would mean decoding it only to encode it again. The adapter costs one re-encode. Surface decodes device bytes into Events, Controller hands those to the on_* methods, and they rebuild the bytes the device sent. That is a genuine inelegance, kept because the alternative -- a byte-level path from Surface into the translator -- touches every Surface backend, and this is the code path that only just started working on Windows. The re-encode is exact, and tests/test_mackie_roundtrip.cpp proves it exhaustively rather than by sampling: all 8192 fader CC/value combinations, both encoder detents on all 8 strips, and every note/velocity pair that decodes to a button, each driven through decode_* and back with the bytes required to match. The domains are small enough that guessing would be a choice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Mackie Control translation existed twice: once in
MackieBackendfor thehost bridge, once in
src/mcu/c8_mcu.cfor the dongle firmware. Two copies of aprotocol mapping drift, and they drift silently — each stays correct against
its own tests while producing different bytes on the wire.
MackieBackendnow owns no translation logic. It holds ac8_mcu_t, feedssurface input into it, and routes its two output callbacks to the MCU port and
to the surface.
Deleted from the C++ side: the MCU note map, the Bank/Nudge/Zoom nav group, the
LCD SysEx parser, the V-pot ring and meter encoding, and the selected-track set.
213 lines removed against 290 added, and most of the addition is the test.
The C module survives because it is the tested one, and because the firmware
compiles that exact file rather than a copy.
Two consequences worth being explicit about
Feedbackgainsraw(), a passthrough for back-ends that emit device bytesthemselves. The translator already produces Command|8 wire format, so routing
its output through the named encoders would mean decoding it only to encode it
again.
The adapter costs one re-encode. Surface decodes device bytes into Events,
Controller hands those to the
on_*methods, and they rebuild the bytes thedevice sent. That is a genuine inelegance. It is kept because the alternative —
a byte-level path from Surface straight into the translator — touches every
Surface backend, and this is the code path that only just started working on
Windows. A follow-up, not a bundled change.
The re-encode is exhaustively verified
tests/test_mackie_roundtrip.cppproves it rather than sampling it:each driven through
decode_*and back, with the bytes required to matchexactly. The domains are small enough that guessing would be a choice.
A lossy round trip would shift control values by a least-significant bit or
two — a fader that never quite reaches unity, an encoder that stops responding —
which is precisely the kind of fault that gets blamed on hardware.
Verified
All 5 test suites pass.
command8-mackiebuilds and fails cleanly with theright message when no MCU port exists. The dongle firmware still builds against
the unchanged
c8_mcu.c, and its own host tests pass.