Skip to content

Add MadMapper .mad file parsing for automated DMX layout#53

Merged
JoshuaBatty merged 8 commits intomasterfrom
worktree-mad_mapper
Mar 25, 2026
Merged

Add MadMapper .mad file parsing for automated DMX layout#53
JoshuaBatty merged 8 commits intomasterfrom
worktree-mad_mapper

Conversation

@JoshuaBatty
Copy link
Member

@JoshuaBatty JoshuaBatty commented Mar 25, 2026

Summary

  • Parse MadMapper v5 .mad binary project files to extract fixture layout, pixel counts, and DMX universe assignments
  • Add per-fixture DMX addressing (DmxMap::PerFixture) alongside existing sequential packing
  • Add Load/Remove UI in Output sidebar with native file dialog (rfd); manual controls hidden when a .mad file is active
  • Path persists in config.json across launches

Test plan

  • parse_known_project — 16 fixtures, 400px each, 6400 total, universes 0-43
  • pixel_count_from_mapping — RGB step detection from pixel mapping string
  • position_extraction — UV coordinates match known values
  • fixtures_by_row_descending_y — sort order verified
  • per_fixture_payloads_route_pixels_to_correct_universes — multi-fixture DMX routing
  • All 14 tests pass, build clean
  • Manual test: load .mad file via Output tab, verify fixture stats display, verify DMX output matches MadMapper universe assignments
  • Manual test: remove .mad file, verify manual controls reappear and work

Parse MadMapper v5 binary project files to derive fixture layout,
pixel counts, and DMX universe assignments automatically instead of
requiring manual configuration. When a .mad file is loaded via the
Output tab, the app uses per-fixture DMX addressing from MadMapper
as the single source of truth. Manual controls remain available when
no project is loaded.
Split led_strip_view into manual and MadMapper paths. The MadMapper
path uses normalised Y coordinates (-1 to +1) so rows are centered
with equal padding top and bottom.
resolve_from_mad_project was being called every frame inside
build_led_worker_input_state, allocating 6400 shader inputs and
sorting fixtures each time. Cache the result on Model and only
rebuild when the project changes (load/remove).
CoreAudio device enumeration was blocking the main thread for
several milliseconds every second, causing a visible stutter.
Now runs on a background thread with results polled via try_recv.
In MM6 files, pixelMapping appears after artnetUniverse rather than
before. Changed field scanning from backward-only to bidirectional
(nearest match within the fixture block window). Added MM6 test.
The MM6 file only contains 15 fixtures (Fixture-Line-16 is absent
from the binary). Assert >= 15 until the MadMapper project is
re-exported with all 16 fixtures.
MM5 stores fixture positions under 'positionUv', MM6 stores them
under 'position' (the 'positionUv' entries in MM6 are all default
0.5,0.5). The parser now tries positionUv first, falls through to
position when positionUv has the default value. Also filters
position key matches by type tag to avoid false matches from
non-fixture uses of the key.
@JoshuaBatty JoshuaBatty merged commit 70cd565 into master Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant