Oplsdt runtime mapping and surface layer for OPSL
  • Rust 51.6%
  • Max 32.9%
  • JavaScript 12.9%
  • Python 1.4%
  • Swift 0.8%
  • Other 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Peter Swimm 680e096598
All checks were successful
ci / codebox (push) Successful in 10s
ci / max-lint (push) Successful in 26s
ci / compiler (push) Successful in 28s
Merge pull request 'docs: Move boot chain, partitions, MCU firmware, recovery and .swu install' (#14) from docs/move-boot-chain-and-swu into main
Reviewed-on: #14
2026-10-05 01:01:46 +00:00
.forgejo Merge stock-rnbo-runner (codebox CI fix) into main 2026-10-04 15:36:20 -07:00
.githooks pre-commit: show build --check output only on failure 2026-10-02 14:54:49 -07:00
compiler compiler: add drift guard test for vendored OPSL schemas 2026-10-04 14:09:35 -07:00
data lpp-move: four pages on the buttons left of the pads; Launchpad sticker map 2026-10-03 15:21:29 -07:00
docs docs: Move boot chain, partitions, MCU firmware, recovery and .swu install 2026-10-04 18:01:22 -07:00
examples lpp-move: M8-native layer over the Launchpad (tracks, MIDI slots, remote keys, per-song projects) 2026-10-03 14:50:45 -07:00
fixtures/m8-lpp M8 links on a stock Move: work around the Takeover's SysEx drops 2026-10-03 12:41:32 -07:00
oplsdt-runner Document the stock runner, M8 Launchpad mode and hardware gates 2026-10-01 17:42:02 -07:00
projects lpp-move: M8-native layer over the Launchpad (tracks, MIDI slots, remote keys, per-song projects) 2026-10-03 14:50:45 -07:00
rnbo lpp-move: show itself after loading; takeover_position param 2026-10-03 17:00:26 -07:00
schemas compiler, schemas: validate movemap.* from vendor/opsl, scope Oplsdt schema ids 2026-10-04 14:09:14 -07:00
tools lpp-move: show itself after loading; takeover_position param 2026-10-03 17:00:26 -07:00
vendor/opsl vendor: re-vendor OPSL schemas and examples at v0.3.0 2026-10-04 14:08:39 -07:00
.gitignore gitignore: local .spel/ forge state 2026-10-03 16:09:03 -07:00
Cargo.lock Add oplsdt-compile: documents to RNBO tables and patchers 2026-10-01 17:42:02 -07:00
Cargo.toml Add oplsdt-compile: documents to RNBO tables and patchers 2026-10-01 17:42:02 -07:00
CONTRIBUTING.md Merge main (org contributor-review policy) into stock-rnbo-runner 2026-10-04 15:21:44 -07:00
LICENSE License under Apache 2.0 2026-10-02 14:10:33 -07:00
OPLSDT_0.2_ARCHITECTURE.md Document the stock runner, M8 Launchpad mode and hardware gates 2026-10-01 17:42:02 -07:00
package.json ci: glob codebox tests so node 22 finds them 2026-10-04 15:25:35 -07:00
README.md docs: point schema locations at vendor/opsl 2026-10-04 14:09:41 -07:00
RELEASING.md lpp-move: show itself after loading; takeover_position param 2026-10-03 17:00:26 -07:00

Oplsdt

Runtime mapping and surface layer for OPSL, plus a runner for a stock Ableton Move.

OPSL describes an instrument: its params, transforms, MIDI bindings and state. Oplsdt describes how you play it: device bundles, section/page layouts, surface profiles and session context. This repo turns those documents into an RNBO graph that runs on an unmodified Move through Cycling '74's RNBO Move Takeover, and that can also act as a Launchpad Pro MK3 for a Dirtywave M8.

The schema and artifact namespace stays movemap.* for compatibility while the project is renamed.

Status: pre-release. M8 Launchpad mode works on a stock Move with an M8 on USB-A (2026-10-03): the M8 links, and LEDs and presses pass both ways. The Oplsdt edit view hasn't been tested on hardware yet. The remaining gates are in docs/verification.md.

Run on a stock Move

You need a Move running the RNBO Move Takeover. No SSH, root access or custom firmware is involved.

  1. Install the Takeover on the Move (Cycling '74 installer).

  2. Import oplsdt.rnbopack from this repo's releases in the RNBO web interface (see importing packages).

  3. Load the oplsdt graph. It has two views; the patcher's /active_view inport picks one (view 0 or 1):

    • View 0: Oplsdt edit. Edit the bundle's instruments with the encoders.
    • View 1: M8 Launchpad. The Move acts as a Launchpad Pro MK3 for the M8.

    The four buttons left of the pads are page buttons in both views, so don't load move-view-controller, which uses them to switch views.

What each view does, and how the graph is wired: docs/stock-runner.md.

Oplsdt edit view

Move control Does
Encoders 1-8 The current page's encoder slots (hold Shift for fine)
Steps 1-8 Layout display_key_1..8 actions (section select, prev/next page)
Steps 9-16 Layout button_1..8 (toggles); otherwise sections in section_order
Buttons left of the pads Page 1-4 of the current section (white = current, lit = available)
Left / Right Previous / next page; walks into the neighbouring section
Jog wheel Next / previous instrument in the bundle (switches while you turn); click shows the current one
Plus / Minus Pad octave up / down
Undo Undo the last param edit; press again to redo
Delete + encoder Reset that param to its default
Pads Notes on the current instrument's channel (fourths layout, poly aftertouch)
Shift + Play Resend every value of the current instrument (resync shadow state)

The controls follow the stock Move where it has an equivalent: Plus/Minus for octave, the jog wheel for browsing, Undo, and Delete + encoder. Back stays with the Takeover, so it still leaves the view.

The display shows the instrument, section, page, eight slot labels with value bars, and the focused param's value. After each action, a boxed message along the bottom says what happened for about 1.5 s (PAGE 2/3 FILTER, OCTAVE +1, UNDO CUTOFF, RESET CUTOFF, the new instrument's name).

M8 Launchpad mode

The Move speaks the Launchpad Pro MK3 programmer-mode protocol to the M8. That covers the device-inquiry reply, programmer-mode handshake, static, flashing and pulsing LEDs, and RGB colour specs. Set the M8 to MIDI Settings → CTRL SURFACE → LAUNCHPAD PRO. Two cable directions are supported:

  • Path A, M8 → Move USB-A. The Move is the USB host. This is the one that works today.
  • Path B, Move USB-C → M8. The M8 is the USB host. It's blocked: the Takeover has no USB-C MIDI port.

The Move has 4×8 pads and the Launchpad has an 8×8 grid, so the jog wheel switches between grid rows 1-4 and 5-8. The buttons left of the pads pick four pages for the steps: NAV (track select, modes), PERFORM (scene launch, arm/mute/solo …), SLOTS (MIDI instrument slots the pads play) and KNOBS (what the encoders control). The function buttons are the Launchpad's, and Move Shift is the Launchpad's Shift. The encoders send CCs on the M8's control map channel for MIDI mapping, and the jog click is the M8's EDIT key. Slots and knobs are set per M8 song in projects/*.json.

Setup and use: docs/m8-user-guide.md. Every control at a glance: open docs/move-control-map.html in a browser. Protocol details, limits (no M8 screen on the Move, M8 audio over line-in only) and how this compares with vlpp_move and Schwung's M8 module: docs/m8-launchpad.md.

Build from source

  • Rust (stable) for the compiler; Node 20+ for the codebox tests.
  • Max 9 with RNBO 1.4+, to export the patchers to the Move.
cargo run -p oplsdt-compile -- validate   # schema-check every example
cargo run -p oplsdt-compile -- build      # regenerate rnbo/patchers/* from the documents
cargo test                                # compiler tests
npm test                                  # run the on-device codebox logic under node

build reads rnbo/oplsdt.build.json. That file names the bundle, the layouts and the surface profiles, and maps repo:// device references to local paths. Unresolved bindings are listed in rnbo/patchers/BUILD-REPORT.md. To export to the Move and package a release, follow RELEASING.md.

Repository layout

Path What
schemas/ Oplsdt-only JSON Schemas: movemap.surface, and the Launchpad map and project (oplsdt.lpp-map, oplsdt.lpp-project)
examples/ Example layouts, sessions, a two-instrument bundle, and surface profiles (Move, emulated Launchpad)
data/ Launchpad palette and the Move ↔ Launchpad control map
projects/ M8 Launchpad projects, one per M8 song: MIDI instrument slots and knob CCs
compiler/ oplsdt-compile: documents → RNBO tables and patchers
rnbo/code/ Hand-written codebox logic (the source of the runtime)
rnbo/patchers/ Generated Max/RNBO patchers, plus vendored Cycling '74 Move drivers
tools/codebox-harness/ Node harness and tests for the codebox logic
tools/move-probe/ MIDI probes for the Move (JACK, on the device) and the M8 (CoreMIDI, on a Mac)
fixtures/m8-lpp/ Launchpad protocol fixtures
vendor/opsl/ Pinned copies of the OPSL schemas (device, movemap.bundle, movemap.layout, movemap.session) and example documents
docs/ Architecture, stock runner, M8 Launchpad (guide, protocol, interactive control map), Takeover MIDI bugs, hardware verification
oplsdt-runner/ Experimental, rooted-Move-only Rust/QuickJS host (reference material)

Core model

  • OPSL owns device identity, params, transforms, capabilities and concrete device state.
  • Oplsdt owns bundles, section/page layouts, surface profiles, runtime session context and surface defaults.
  • The runner never interprets JSON on the device. The compiler turns the documents into lookup tables, and the RNBO patchers only index those tables.

Device references in the examples point at the public OPSL repo (repo://Toilville/opsl/...); vendor/opsl/ pins the OPSL schemas (device and movemap.*) and example copies used by the build. Oplsdt-only schemas (movemap.surface, oplsdt.lpp-map, oplsdt.lpp-project) stay in schemas/.

See OPLSDT_0.2_ARCHITECTURE.md for the full model, and docs/rnbo-move-architecture.md for the Move hardware and RNBO stack notes.

Experimental: rooted runner

oplsdt-runner/ is the recovered Rust/QuickJS JACK host. It needs SSH root on the Move and is incomplete. It stays as reference material and is not part of the stock-unit path.

License

Apache License 2.0. See LICENSE.

The vendored Cycling '74 Move drivers in rnbo/patchers/ (input-driver.rnbopat, led-driver.rnbopat) are MIT-licensed; see rnbo/patchers/CYCLING74-LICENSE.md.