SolarOS

SolarOS 4.13.4 manual · api

Lua audio and control API

API overview · Python audio and control

solaros.controls

solaros.parameters

solaros.midi

solaros.osc

solaros.dsp

solaros.audio

solaros.synth

MIDI

The MIDI job must own a running bus before Lua transmits or receives. The following setup creates a bus, starts the worker, sends a note, and waits up to one second for a non-consuming subscriber message:

solaros.buses.create_midi("midi0", { tx = 2, rx = 3 })
solaros.jobs.start("midi", { "midi0" })
solaros.midi.note_on(1, 60, 100)
local message = solaros.midi.read(1000)

status() includes traffic, parser, drop, error, CC-stream, and script subscription state. send(status[, data1, data2]) validates raw messages; note_on, note_off, cc, and program provide channel-oriented helpers. read() and its receive() alias return a message table or nil, are bounded to 60 seconds, and are cancellation-aware. The subscription is automatically released when Lua exits; close() releases it earlier.

Use streams(), stream_add(channel, controller), stream_remove(...), and stream_clear() to manage incoming CC scalar streams. Message tables contain status, length, type, and applicable channel/data fields.

Open Sound Control

Lua configures native OSC bindings while the osc job retains UDP socket, filtering, and rate-limit ownership:

solaros.osc.bind_stream(
    "ambient", "temperature", "/room/temperature", 2.0, 0.1
)
solaros.jobs.start(
    "osc", { "listen=9000", "target=192.168.1.50:9001" }
)

bindings() returns source configuration plus availability, values, timing, send counters, and errors. bind_stream, bind_event, and bind_control return numeric IDs; unbind and clear remove definitions. Event edges are "rising", "falling", or "both"; rates are 0.1..100 Hz.

encode_float() and encode_int() return binary OSC messages that can be sent with solaros.net.udp_send(). dispatch(packet) validates a message or immediate bundle and applies the same native parameter routes as the job. limits() reports all public codec and binding bounds.

Synthesizer example

For example, this plays a short saw-wave chord without running Lua in the real-time render callback:

solaros.synth.configure("saw", 5, 80, 65, 140)
solaros.synth.configure_oscillator2("square", 0, 7, 35)
solaros.synth.configure_filter(1200, 35, 80, 5, 250, 20, 180)
solaros.synth.configure_performance(true, 80)
solaros.synth.note_on(440, 110)
solaros.synth.note_on(554, 90)
solaros.time.sleep_ms(250)
solaros.synth.all_notes_off()
solaros.time.sleep_ms(150)
solaros.synth.stop()

note_on() accepts 20 through 8000 Hz and velocity 1 through 127. Envelope times accept 0 through 10000 ms and sustain accepts 0 through 100 percent. The configure() updates active voices immediately and also sets the defaults for future notes. configure_filter() accepts cutoff from 40 through 18000 Hz, resonance and envelope amount from 0 through 100 percent, followed by its own attack, decay, sustain, and release values. The first note claims exclusive audio output lazily, and the runtime releases it automatically when the script exits or is interrupted. configure_oscillator2() accepts waveform, octave from -2 through +2, fine detune from -100 through +100 cents, and mix from 0 through 100 percent. Mix zero bypasses oscillator 2 exactly. Both oscillators share the filter and envelopes. configure_performance() selects polyphonic or monophonic last-note playback and accepts a glide time from 0 through 2500 ms.

DSP values

For the Q15 numeric contract, processor lifetime, limits, and examples, see Digital signal processing. Lua DSP operations return new binary strings because ordinary Lua strings are immutable.

Quick reference

Use solaros.audio, solaros.synth, solaros.dsp, solaros.controls, solaros.parameters, solaros.midi, solaros.osc for audio and control. See man lua for runtime conventions and service availability.

Join us on: