![]() |
uvi-script
Musical event scripting with Lua
|
uvi-script is built on the Lua programming language, a lightweight, fast, and embeddable scripting language. Understanding Lua is essential for writing effective uvi-scripts.
This page covers the Lua-specific aspects of uvi-script: which version is used, what libraries are available, and the real-time constraints that shape how you write scripts.
If you're new to Lua or need a reference, we recommend these excellent resources:
These resources are well-written and provide a solid foundation for scripting. Using a simple, widespread, yet powerful scripting language that can be learned online was one of the main motivations for choosing Lua.
What you need to know:
uvi-script uses a sandboxed Lua 5.1 virtual machine with custom extensions designed for real-time audio processing.
Most script code executes with real-time priority to ensure sample-accurate timing and low-latency performance. This places specific constraints on what you can do:
Real-Time Requirements:
Exceptions (Non-Real-Time): These callbacks run with relaxed constraints and can allocate memory:
To maintain real-time safety, uvi-script uses a pre-allocated memory pool for all Lua operations during real-time execution.
Best Practices:
uvi-script provides access to a subset of Lua's standard libraries. Libraries that require operating system access or blocking I/O are not available to maintain real-time safety.
base - Basic Functions
assert, error, pcall, type, tonumber, tostringpairs, ipairs, nextprint, select, unpackrequire - Load Lua modulestable.insert, table.removetable.concattable.sorttable.copy(t) - uvi-script extension: creates a shallow copy of a tablestring - String Operations
string.sub, string.find, string.matchstring.format, string.gsubmath - Mathematical Functions
math.sin, math.cos, math.tan, math.asin, etc.math.abs, math.floor, math.ceil, math.min, math.maxmath.random, math.randomseedmath.pi, math.hugebit - Bitwise Operations
bit.band, bit.bor, bit.bxor, bit.bnot, bit.lshift, bit.rshiftclass - Object-Oriented Programming
os - Operating System Facilities
io - File I/O
Third-Party Lua Libraries
The runtime replaces a few base library functions with script-friendly versions and adds several global helpers.
print(...) writes to the script console, not to a standard output stream. Arguments are converted to text and separated by single spaces (the standard print separates them with tabs). Event tables — tables carrying a numeric type field, such as the argument of onNote — are expanded to their key=value contents instead of being shown as a table address:
Other tables print as an address, like with the standard print; use the helpers below to display their contents.
print_table(t, printer, indent) prints one key:value line per entry and recurses into nested tables, indenting each nesting level by two extra spaces. printer (optional) is the output function, print by default; indent (optional) is the initial indentation string. Values that are not booleans, numbers, or strings are shown by their type name.
table.tostring(t) returns the top-level key=value pairs of a table as a single space-separated string. Pairs appear in unspecified order and nested tables appear as addresses.
table.print(t) prints table.tostring(t) wrapped in braces. Does nothing if t is not a table.
table.copy(t) returns a new table with the same keys and values. The copy is shallow: nested tables are shared with the original, not duplicated.
assert(cond, msg, level) raises an error with message msg (default "error") when cond is false or nil. Unlike the standard assert, it takes a third level argument selecting the stack level at which the error is reported: 1 (the default) blames the caller of assert, 2 blames the caller's caller, and so on — useful for reporting argument errors at the call site of your own functions. Also unlike the standard version, it does not return its arguments on success.
warning(condition, msg, level) has the same signature but never raises an error: when condition is false it prints msg prefixed with warning: [file]:line, where the location is taken from the stack level selected by level (default 1, the caller of warning).
uvi-script includes a built-in class system. Use class to define classes with constructors, methods, and instance state. This is useful for encapsulating complex logic like sequencers, state machines, or multi-voice managers.
Create instances with the class name as a function call:
The synthesis engine objects (Program, Layer, Keygroup, Oscillator, etc.) are C++ objects exposed to Lua. They support the same colon method syntax:
uvi-script uses Lua coroutines internally to implement its cooperative threading model. Each event callback (onNote, onRelease, etc.) runs as a separate coroutine that can be suspended using wait, waitBeat, or waitForRelease.
What you need to know:
wait() functionsFor detailed information about threading and timing, see Threading and Timing.