![]() |
uvi-script
Musical event scripting with Lua
|
Functions | |
| void | onInit () |
| initial callback that is called just after the script initialisation if the script was successfully analyzed. | |
| void | onLoad (table data) |
| callback that is called when restoring a ScriptProcessor state if custom data has been saved. | |
| table | onSave () |
| callback that is called when saving the ScriptProcessor state. | |
| void | onEvent (table e) |
| event callback that will receive all incoming events if defined. | |
| void | onNote (table e) |
| event callback that will receive all incoming note-on events if defined. | |
| void | onRelease (table e) |
| event callback executed whenever a note off message is received. | |
| void | onProgramChange (table e) |
| event callback that will receive all incoming program-change events if defined. | |
| void | onController (table e) |
| event callback that will receive all incoming control-change events when defined. | |
| void | onPitchBend (table e) |
| event callback that will receive all incoming pitch-bend events if defined. | |
| void | onAfterTouch (table e) |
| event callback that will receive all incoming channel after-touch events if defined. | |
| void | onPolyAfterTouch (table e) |
| event callback that will receive all incoming polyphonic after-touch events if defined. | |
| void | onTransport (bool playing) |
| event callback that is called when the host transport bar state changes. | |
Event-driven callback functions that define your script's behavior.
Event callbacks are functions you define that are automatically called when specific events are received by the ScriptProcessor. The default behavior (if you don't define a callback) is to forward incoming events unchanged to the output.
Threading Model:
Each callback executes as an independent cooperative micro-thread (Lua coroutine) with its own environment. Unlike traditional OS threads, callbacks cannot be interrupted unless they explicitly yield using wait, waitBeat, or waitForRelease. During suspension, other callbacks can start or resume in parallel.
Available Callbacks:
Transport:
State Management:
| void onAfterTouch | ( | table | e | ) |
event callback that will receive all incoming channel after-touch events if defined.
AfterTouch to pitch Example:
| e | event table with the following fields:
|
| void onController | ( | table | e | ) |
event callback that will receive all incoming control-change events when defined.
Example:
Be aware that you need to forward MIDI CC using postEvent(e) if you want your users to be able to MIDI learn script parameters or use pre-programmed MIDI CC modulations.
| e | event table with the following fields:
|
| void onEvent | ( | table | e | ) |
event callback that will receive all incoming events if defined.
If this callback is defined it will take over the other more specialized callbacks like onNote, onRelease. All incoming events are tables with at least the type field defined.
| e | event table, see other callbacks for the different kind of table fields |
Example:
| void onInit | ( | ) |
initial callback that is called just after the script initialisation if the script was successfully analyzed.
This the place to start a background process that doesn't require external input like algorithmic event generation.
Example:
initial callback that is called just after the script initialisation if the script was successfully analyzed.
Hierarchical IR menu with userReady guard
A hierarchical Menu (path-based entries grouped by "/") that loads an impulse response into a SampledReverb insert. The menu's selection is persisted with the preset, so the user's chosen IR survives a save / load round-trip.
Why this example shows the userReady flag:
When a preset loads, the engine restores every persistent widget to its saved value. For widgets whose .changed callback performs an expensive side effect (here loadImpulse, which hits the disk), we must not let that callback fire during the restore — the IR is already in the patch.
The standard guard:
userReady = false at script load,true in onInit (which fires AFTER preset state has been fully restored),.changed early-return when the flag is false.With the guard in place, only real user clicks trigger loadImpulse. The same pattern protects any expensive .changed side effect: loadSample, network calls, rebuilding a big lookup, etc. See Chorder for the alternative pattern when the menu writes into other widgets and you want the menu non-persistent.
@demonstrates onInit, Menu, Label, loadImpulse, hierarchical menu, userReady guard
| void onLoad | ( | table | data | ) |
callback that is called when restoring a ScriptProcessor state if custom data has been saved.
This is called just after the script initialisation and after restoring widgets values when the processing hasn't started yet.
| data | a lua value as saved by your onSave function |
Example:
| void onNote | ( | table | e | ) |
event callback that will receive all incoming note-on events if defined.
Example:
| e | event table with the following fields:
|
| void onPitchBend | ( | table | e | ) |
event callback that will receive all incoming pitch-bend events if defined.
Example:
| e | event table with the following fields:
|
| void onPolyAfterTouch | ( | table | e | ) |
event callback that will receive all incoming polyphonic after-touch events if defined.
Example:
| e | event table with the following fields:
|
| void onProgramChange | ( | table | e | ) |
event callback that will receive all incoming program-change events if defined.
Program Change to MIDI channel Example:
| e | event table with the following fields:
|
| void onRelease | ( | table | e | ) |
event callback executed whenever a note off message is received.
Release trigger Example:
| e | event table with the following fields:
|
| table onSave | ( | ) |
callback that is called when saving the ScriptProcessor state.
This is the place where you can save additional data if you need to. Supported lua types are number, boolean, strings and (nested) tables without (cyclic) references.
Example:
callback that is called when saving the ScriptProcessor state.
Chord Harmonizer with Presets
Generates chords by playing up to 6 simultaneous notes with configurable pitch shifts and velocity scaling. Ships with several named presets (Major, Fifth, Jazz, Debusian, etc.) selectable from a Menu widget.
Worth studying: the preset Menu pattern. The Shift / Velocity knobs are left .persistent = true (default) so the engine round-trips their values across save / load. The preset Menu itself is .persistent = false so the engine does NOT restore it via the normal path — that would fire its .changed callback during the restore and overwrite the just-restored knob values. We round-trip the menu's visual selection ourselves with setValue(index, false) in onLoad, where the second arg false tells the widget NOT to fire .changed. The user's last-picked preset name is shown again, the knobs keep their tweaks, and no side effect re-fires.
@demonstrates playNote, Knob, Menu, onSave, onLoad, .persistent, setValue notify flag
| void onTransport | ( | bool | playing | ) |
event callback that is called when the host transport bar state changes.
| playing | boolean flag that tells whether the transport bar is in playing state |
Example: