- Rust 51.6%
- Max 32.9%
- JavaScript 12.9%
- Python 1.4%
- Swift 0.8%
- Other 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo | ||
| .githooks | ||
| compiler | ||
| data | ||
| docs | ||
| examples | ||
| fixtures/m8-lpp | ||
| oplsdt-runner | ||
| projects | ||
| rnbo | ||
| schemas | ||
| tools | ||
| vendor/opsl | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| OPLSDT_0.2_ARCHITECTURE.md | ||
| package.json | ||
| README.md | ||
| RELEASING.md | ||
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.
-
Install the Takeover on the Move (Cycling '74 installer).
-
Import
oplsdt.rnbopackfrom this repo's releases in the RNBO web interface (see importing packages). -
Load the
oplsdtgraph. It has two views; the patcher's/active_viewinport 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.