Signals
Signals are continuous control sources for modulating parameters. Bind one to an effect, track, or send parameter with <<. Import constructors from std/signals:
use "std/signals" { Sine, hz_to_periods };| Constructor | Output | Meaning |
|---|---|---|
Sine(freq?) / Sine2(freq?) | 0–1 / -1–1 | Sine wave |
Saw(freq?) / Saw2(freq?) | 0–1 / -1–1 | Sawtooth — ramps up, then resets |
Tri(freq?) / Tri2(freq?) | 0–1 / -1–1 | Triangle wave |
Square(freq?) / Square2(freq?) | 0 or 1 / -1 or 1 | Square wave, 50% duty cycle |
Rand(freq?) | 0–1 | Sample-and-hold random (deterministic) |
Perlin(freq?) | 0–1 | Smooth, continuous Perlin noise |
automation(...breakpoints) | breakpoint values | Breakpoint envelope with curves |
signal(pattern) | pattern values | Stepped signal from a pattern |
signal_ramp(start, end, duration?) | start–end | Linear ramp, clamps at endpoints |
Cc(cc) / Cc(channel, cc) | 0–1 | MIDI CC input |
Cc_learn() | 0–1 | Bind to the next CC knob you move |
| Method | Returns | Meaning |
|---|---|---|
range(min, max) | Signal | Map output linearly to [min, max] |
range_exp(min, max) | Signal | Map output exponentially (for frequencies) |
retrigger(mode) | Signal | Phase reset: "cycle", "beat", or "free" |
continuous() | Signal | Keep global clock phase across rebinds |
smooth(time_ms) | Signal | One-pole lowpass smoothing |
at(time, value [, curve]) | Signal | Add a breakpoint (automation signals only) |
in_seconds() | Signal | Switch automation time base to seconds |
set_param(name, value) | Signal | Set a DSP signal parameter |
Oscillators
Section titled “Oscillators”All oscillators take one optional frequency argument in periods per cycle (default 1 — one full wave per cycle). Pass a number for tempo-relative speed, or convert from absolute time with hz_to_periods() / sec_to_periods():
use "std/signals" { Sine, Saw, Tri2, Rand, hz_to_periods, sec_to_periods };
let once = Sine(); // one period per cyclelet wobble = Saw(4); // four periods per cyclelet sweep = Tri2(0.25); // one period across four cycleslet fixed = Sine(hz_to_periods(2)); // 2 Hz, independent of tempolet slow = Rand(sec_to_periods(3)); // one new value every 3 secondsEach waveform comes in a unipolar form (0 to 1, for parameter modulation) and a bipolar form with a 2 suffix (-1 to 1, for audio-style modulation and signal algebra).
use "std/signals" { Sine, Sine2, Square2, Perlin };use "std/effects" { Delay };use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
let d = Delay(0.25, 0.5);drums.load_effect(d);d.param("Time") << Sine(2).range(0.1, 0.4);d.param("Feedback") << Perlin(1).range(0.2, 0.6);Automation
Section titled “Automation”automation(…breakpoints)
Section titled “automation(…breakpoints)”Breakpoint envelope. Each breakpoint is #[time, value] or #[time, value, curve]; time is in cycles by default.
use "std/signals" { automation };use "std/effects" { Lowpass };use "std/instruments" { Sampler, Kit };
let hats = AudioTrack("hats");hats.load_instrument(Sampler(Kit("CR-78")));hats << [hh*8];
let lpf = Lowpass(1000);hats.load_effect(lpf);lpf.param("Cutoff") << automation(#[0, 400], #[4, 4000, "exp"], #[8, 400]);Call it empty and chain .at() for the builder form:
use "std/signals" { automation };
let env = automation().at(0, 400).at(4, 2000, "smooth").at(8, 400);| Curve | Shape |
|---|---|
"linear" | Straight line (default) |
"step" | Instant jump at the breakpoint |
"exp" | Exponential curve |
"smooth" | Smooth interpolation |
"ease-in" / "ease-out" / "ease-in-out" | Slow start / slow end / both |
"ease" | CSS-style ease |
"bezier(x1,y1,x2,y2)" | Custom cubic Bézier |
at(time, value [, curve])
Section titled “at(time, value [, curve])”Add a breakpoint to an automation signal (chainable; automation signals only). Curve defaults to "linear".
in_seconds()
Section titled “in_seconds()”Switch an automation signal’s time base from cycles to seconds (automation signals only).
use "std/signals" { automation };
let env = automation(#[0, 400], #[1.5, 2000]).in_seconds();MIDI Input
Section titled “MIDI Input”Both constructors require an active MIDI input connection.
Cc(cc) / Cc(channel, cc)
Section titled “Cc(cc) / Cc(channel, cc)”MIDI CC input as a 0–1 signal. One argument reads the CC from any channel; two arguments pin it to a channel (0–15). CC numbers are 0–127.
use "std/signals" { Cc };
let mod_wheel = Cc(1);let ch1_cutoff = Cc(0, 74);Cc_learn()
Section titled “Cc_learn()”Blocks until you move a CC knob or fader (10-second timeout), then returns a signal bound to that exact channel and CC number.
use "std/signals" { Cc_learn };
let cutoff = Cc_learn(); // move a knob nowOther Constructors
Section titled “Other Constructors”signal(pattern)
Section titled “signal(pattern)”Stepped signal from a pattern — outputs the value of the active event (0 during rests).
use "std/signals" { signal };use "std/effects" { Delay };use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
let d = Delay(0.25, 0.5);drums.load_effect(d);d.param("Time") << signal(#[0, 50, 100, 50]).range(0.1, 0.5);signal_ramp(start, end, duration?)
Section titled “signal_ramp(start, end, duration?)”Linear ramp from start to end over duration cycles (default 1), holding at end afterwards.
use "std/signals" { signal_ramp };use "std/effects" { Lowpass };use "std/instruments" { Sampler, Kit };
let hats = AudioTrack("hats");hats.load_instrument(Sampler(Kit("CR-78")));hats << [hh*8];
let lpf = Lowpass(400);hats.load_effect(lpf);lpf.param("Cutoff") << signal_ramp(400, 4000, 4); // 4-cycle sweepSignal Algebra
Section titled “Signal Algebra”Signals combine with each other and with numbers using arithmetic operators; the result is a new signal evaluated sample-wise.
| Operator | Example | Meaning |
|---|---|---|
+ | Sine(1) + Saw(3) | Addition |
- | Sine(1) - Tri(2) | Subtraction |
* | Sine(1) * Sine(7) | Multiplication (ring mod) |
/ | Sine(1) / 2 | Division |
- (unary) | -Sine(1) | Negation |
use "std/signals" { Sine, Saw };
let scaled = Sine(4) * 0.5; // halve the amplitudelet offset = Sine(2) + 0.3; // DC offsetlet complex = (Sine(1) + Saw(3) * 0.5).range_exp(200, 8000).smooth(5);Signal Methods
Section titled “Signal Methods”range(min, max)
Section titled “range(min, max)”Map the signal’s output linearly to [min, max].
use "std/signals" { Sine };
let lfo = Sine(4).range(0.2, 0.8);range_exp(min, max)
Section titled “range_exp(min, max)”Map exponentially — equal output movement covers equal pitch intervals. Use this for frequency parameters.
use "std/signals" { Sine };
let cutoff_lfo = Sine(1).range_exp(200, 4000);retrigger(mode)
Section titled “retrigger(mode)”Set the phase-reset mode: "cycle" resets phase every cycle, "beat" every beat, "free" never.
use "std/signals" { Sine };
let locked = Sine(4).retrigger("beat");continuous()
Section titled “continuous()”Opt out of bind-time phase reset. By default a signal restarts its local clock at the next cycle boundary after binding; .continuous() keeps it on the global playback clock, so re-evaluating a line tweaks the LFO without resetting its phase.
use "std/signals" { Sine, hz_to_periods };use "std/effects" { Lowpass };use "std/instruments" { Sampler, Kit };
let hats = AudioTrack("hats");hats.load_instrument(Sampler(Kit("CR-78")));hats << [hh*8];
let lpf = Lowpass(1000);hats.load_effect(lpf);lpf.param("Cutoff") << Sine(hz_to_periods(2)).range(200, 4000).continuous();smooth(time_ms)
Section titled “smooth(time_ms)”One-pole lowpass smoothing — removes zipper noise from stepped sources like MIDI CC.
use "std/signals" { Cc };
let smoothed = Cc(74).smooth(50).range(200, 4000);set_param(name, value)
Section titled “set_param(name, value)”Set a named parameter on a DSP signal instance (chainable). DSP signals also support set_buffer(name, data) and get_buffer(name) for buffer access.
Visualizing Signals
Section titled “Visualizing Signals”scope(signal [, label])
Section titled “scope(signal [, label])”Register a signal for scope visualization in the editor. The label defaults to a description of the signal.
use "std/signals" { Sine };
scope(Sine(2).range(0.2, 0.8), "lfo");DSP Signals
Section titled “DSP Signals”Define custom compiled signals with the dsp signal block — params, state, buffers, and per-sample code running in the audio engine. Instances are ordinary signals: all methods above apply, and they bind with << like any other signal. See DSP Signals, Functions & Objects for the block syntax and DSP Reference for the built-in functions available inside.
See Also
Section titled “See Also”- Instruments & Effects — effect parameters and
<<modulation - Track Methods — sends and track parameters that accept signals
- Signals & Automation — guided chapter
- DSP Reference — built-ins for custom DSP signals