← All docs
Mapping

Transform nodes — clamp, scale, hold-timer, latch, more

A Transform node (v0.5+) sits between a source and a sink. It consumes an event on its left handle and emits one or more events on its right handles. Compose them to build behaviour that doesn't fit on a single sink.

Adding one

Topbar → Transform spawns a node at the canvas centre. The inspector lets you pick an operation; each operation has its own param fields.

The op set

Pure value ops

These stateless ops just reshape the value flowing through.

  • Clamp — limit v to a min/max range. Anything outside is pinned to the nearest bound.
  • Scale — affine remap. v ∈ [inMin, inMax] → [outMin, outMax]. The classic use: a MIDI fader's full 0..1 sweep should only drive Resolume opacity from 0.3..0.8.
  • Invert1 − v for continuous, press↔release for discrete.
  • Curve (gamma) — exponential / logarithmic shape. gamma = 1 is linear, > 1 is slow start / fast end, < 1 is fast start / slow end.

Stateful event ops

These remember state per (transformNodeId, sourceId) — separate state per source, so one hold-timer shared by two inputs doesn't get its timer crossed.

  • Hold timer — discrete-only. Two outputs:
- tap — fires when the press is released before thresholdMs (default 500 ms). Pulse: press immediately followed by release. - hold — fires thresholdMs after press (still held); releases when the actual button is released. Wire tap to one OSC out and hold to a different one to get tap-vs-hold gestures from one button.
  • Double-tap — emits on the second press inside windowMs (default 350 ms). First press is swallowed.
  • Threshold — hysteresis on a continuous value. Crosses up → emits high. Crosses down (lower) → emits low. Use to drive a discrete sink off a noisy continuous source without flapping.
  • Latch — each press toggles internal state, emits 1 / 0 alternately. Same as a sink-side toggle mode but one hop earlier so it can drive multiple sinks.
  • Edge — fires once on a rise (cross up through 0.5), fall (cross down through 0.5), or both. Useful for converting a continuous source into a discrete pulse at a given threshold.

Wiring

A transform node has:

  • One input handle on the left — accepts wires from any source or another transform.
  • One or more output handles on the right — wire to sinks (or further transforms).

Multi-output ops (hold-timer, threshold) expose two stacked output handles. Single-output ops have one default handle.

The dispatch depth cap (8 hops; see Node graph → Loop protection) bounds chains, so accidentally wiring a latch → invert → latch cycle through the same source terminates rather than runs away.

Example: tap vs hold

KbInput "F1" ──► Hold timer (500ms)
                    │ tap  ──► OSC Out  /scene/1/preview
                    │ hold ──► OSC Out  /scene/1/go

Quick press of F1 previews the scene; hold for half a second to actually go.

Example: scale a noisy axis

Gamepad axis ──► Scale (0..1 → 0.3..0.8) ──► Resolume Out  /composition/layers/1/video/opacity

The full stick travel maps to opacity 30 %–80 %, with no dead end at 0 or 100 %.

Example: latch with broadcast

KbInput "Space" ──► Latch ──► OSC Out  /strobe   (1/0 toggle)
                          └─► Resolume Out  /composition/groups/2/bypassed   (1/0 toggle)

A single press toggles the strobe on, sends the same on/off to Resolume — both stay in sync because they share the latch state.