Script Engine Overview
Neurode MIDI v2 uses NeuroScript 2.0 as the canonical way to express routing/transforms.
Canonical encoding (v2)
- NeuroScript 2.0 source is canonical (presets export/import as source).
- Visual authoring is allowed, but it compiles to NeuroScript (no TransformGraph/DAG runtime requirement).
- Lua scripting is supported, but NeuroScript remains canonical for v2 encoding/export.
What is the Script Engine?
The Script Engine lets you write custom MIDI effects using code. Every MIDI event enters your script, you process it, and return the transformed output.
Languages:
- NeuroScript 2.0 — Canonical, bounded, deterministic
- Lua — Fully supported alternative (non-canonical encoding)
Quick Validation
Try the Neuroscript Simulator for quick, single-event tests without creating a full route.
How It Works
NeuroScript compiles to an immutable execution plan. Each MIDI event flows through your script's filter, transform, and routing statements. The script operates on messages deterministically with bounded execution.
Lua scripts can be used as an alternative, providing a function body that processes each event in real-time.
Quick Start
Try a quick transform
Here's a simple NeuroScript example:
# Keep notes on channel 1, transpose up an octave
keep note where ch == 1
transpose +12
vel clamp 50..110
passFor more advanced control, you can use Lua:
-- Drop notes below C3
if event.type == "noteOn" and event.data1 < 48 then
return {} -- Drop event
end
return eventWhich Language Should I Use?
- NeuroScript 2.0 — Preferred: deterministic, compiles to an immutable execution plan with bounded execution guarantees
- Lua — Supported alternative for custom scripting needs
If you're building or sharing presets, prefer NeuroScript so the preset is portable and auditable.
State & Memory (v2)
NeuroScript 2.0 provides fixed-size Int32 register banks that scripts can read/write deterministically.
Scopes:
- stream — Per MIDI stream
- channel — Per channel (1–16)
- source — Per input source
- global — Shared across all routing
Example
# Count note-on events in a stream-scoped register
when type == note_on {
register("noteCount") + 1 -> register("noteCount")
}
passUse cases:
- Count events for patterns (every Nth note)
- Share coarse state between routes (global)
- Coordinate per-channel behavior without locks
Next Steps
- Neuroscript Language — Learn the canonical language
- Lua API — Lua scripting reference (non-canonical)
- Event Model — Deep dive into MIDI event structure
Performance
The engine tracks per-event execution time. Keep loops tight and prefer numeric operations for best results.
