Maschine Mk3: dual-screen support with frame-diff partial updates - #115
Maschine Mk3: dual-screen support with frame-diff partial updates#115RufusIbiza wants to merge 6 commits into
Conversation
…and build files, and remove the valgrind_jack suppression file.
…e docs The async USB write pipeline silently dropped the second screen's transfers once the inflight counter hit its cap of 10. Switched Mk3 screen blits to synchronous bulk transfers so both screens get fair access to the shared USB endpoint. The example now diffs each frame against the previous one and sends only the dirty bounding box via blit_zone, with a full-screen keyframe every 60 frames. This cuts per-frame USB traffic from ~522 KB to just the changed region, leaving headroom for both screens to update smoothly. Rewrote the Mk3 resource docs (mappings, partial screen protocol) and the project README with build instructions, device table, usage guide, and project layout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
harryhaaren
left a comment
There was a problem hiding this comment.
Cannot be merged as is. Reviewed commit by commit, saw the first is good, 2nd is bad, 3rd fixes up some of the accidentally introduced stuff. Lots more cleanup to be done.
Before you do the work - lets sync on what/if the longer term goal is - i'm not sure Ctlra in this shape is very useful unless actively maintained and improved - and I'm not sure if I'll have/make/find bandwidth to be that active in maintaining etc the library.
| @@ -0,0 +1,19 @@ | |||
| #!/bin/bash | |||
There was a problem hiding this comment.
if a new example is required, it should be integrated into the existing build system.
| cairo_set_source_rgb(cr, 0.05, 0.05, 0.08); | ||
| cairo_rectangle(cr, 0, 0, WIDTH, HEIGHT); | ||
| cairo_fill(cr); | ||
|
|
There was a problem hiding this comment.
A lot of this code looks familiar (from AVTK, AVTKA or Ctlra example code i'm not sure anymore, but duplication is never good..)
| @@ -0,0 +1,131 @@ | |||
| #include <libusb-1.0/libusb.h> | |||
There was a problem hiding this comment.
not sure what value this adds, ctlra can already print what USB devices it knows, or "usbview" or lsusb linux tools would do this too.
| @@ -0,0 +1,75 @@ | |||
| # D2 LED Mapping Discovery Results | |||
There was a problem hiding this comment.
Useful to have the data, but a machine readable format (JSON or .ini or something small/easy to parse without deps ideally..) would allow this to be updated/fixed if there were issues?
| @@ -0,0 +1,75 @@ | |||
| # VirtualDJ D2 Screen Communication Analysis | |||
There was a problem hiding this comment.
interesting info, I hadn't investigated that in detail before. not sure we want to commit all the AI generated files.
| // --- 1. Main Screen Data Packet Construction and Sender --- | ||
| // Address: 140c40860 | ||
| // Constructs the 20-byte magic header and the nested 16/20-byte rectangle command. | ||
| uint32_t sub_140c40860(void* arg1, int64_t arg2, int32_t x, int32_t width, int32_t height, char display_part, int32_t stride) |
There was a problem hiding this comment.
messy function names etc - this is research/POC code, not ready for merging.
| @@ -0,0 +1,64 @@ | |||
| #ifndef CTLRA_NI_MASCHINE_MK3_H | |||
There was a problem hiding this comment.
Pretty sure that a bunch of these were already somewhere in the Ctlra repo - perhaps on another branch? Is this duplicate..?
| * from ctlra->ctx. Without also pumping NULL here, async bulk-write | ||
| * completion callbacks never fire, USB_XFER_INFLIGHT_WRITE never | ||
| * decrements, and new screen blits are silently dropped after 10. */ | ||
| libusb_handle_events_timeout_completed(NULL, &tv, NULL); |
There was a problem hiding this comment.
nice bugfix in the middle of everything else.. this should probably be a seperate commit.
|


Summary
Adds full Maschine Mk3 dual-screen support to openAV-Ctlra, with efficient partial screen updates that match the Kontrol D2's capabilities.
Screen API
ni_maschine_mk3_screen_get_pixels(dev, screen_idx)-- access each screen's pixel buffer independentlyni_maschine_mk3_screen_blit(dev, screen_idx)-- full-frame update (used for keyframes)ni_maschine_mk3_screen_blit_zone(dev, screen_idx, x, y, w, h)-- partial update of just the dirty bounding boxDual-screen USB fix
The async USB write pipeline silently dropped the second screen's transfers once the inflight counter hit its cap. Switched Mk3 screen blits to synchronous bulk transfers so both screens get fair access to the shared endpoint.
Frame-diff partial updates
The example diffs each frame against the previous one and sends only the dirty bounding box via
blit_zone, with a full-screen keyframe every 60 frames. This cuts per-frame USB traffic from ~522 KB down to just the changed region, leaving headroom for both screens to update smoothly.New header and example
ctlra/devices/ni_maschine_mk3.h-- public API and all button/encoder definesexamples/maschine_mk3/-- Cairo-based dual-screen graphics demo with buttons, pads, encoders, and touchstripDocumentation
resources/maschine_mk3/PARTIAL_SCREEN_UPDATES.md-- full API reference, frame-diff pattern, pixel format, USB detailsresources/maschine_mk3/MASCHINE_MK3_MAPPINGS.md-- all control mappings with tablesTest plan
examples/maschine_mk3/run_maschine_mk3.sh