Skip to content
Русский

Variables

Eighteen read-only variables carry the live audio analysis into your expressions, plus five that carry position rather than sound: index for a per-element evaluation, and x/y/rad/ang for a per-vertex one.

VariableMeaningNotes
bassBass-band level (~20–250 Hz), as a fraction of its own recent peak.0–1. > 0.5 means “loud for this track”.
midMid-band level (~250–4000 Hz), same basis.0–1.
trebTreble-band level (~4–18 kHz), same basis.0–1; reads lowest of the three on most material.
onsetOnset/attack strength, as a fraction of its own recent peak.0–1. A transient, not a level — spikes on hits.
beat1.0 on a hop where a beat fired, else 0.0.A gate: beat * k adds k only on beat frames.
barBeat phase in [0, 1): 0 on each beat, ramping to the next.A misnomer kept for compatibility — for real bar position use bar_phase.
timeThe scene clock in seconds (monotonic).Use time * k for slow drift; k sets the speed.
tempoTracked tempo in BPM.Not a 0–1 band — see the warning below.
noveltySpectral-change transient: ~0 within a steady segment, spiking at a track/section boundary.Experimental — see below.
bass_rawAbsolute bass magnitude — the pre-normalization value.Raw and small (mean 0.040): multiply up and clamp.
mid_rawAbsolute mid magnitude.Raw and small (mean 0.006).
treb_rawAbsolute treble magnitude.Raw and small (mean 0.006).
onset_rawAbsolute spectral flux.Raw and very small (mean 0.002).
beat_indexMonotone onset counter, 0 before the first detection.Integer-valued, and not a musical period — mod(beat_index, 4) is not “every 4th beat”. See Musical time.
time_since_beatSeconds since the last beat; exactly 0 on a beat hop.A retriggered ramp — good for decays.
beat_in_barWhich beat of the bar, 0–3.beat_in_bar == 0 is the downbeat.
bar_indexBar counter — monotone except across an alignment change.mod(bar_index, 8) for an 8-bar arc, which a lock can repeat or drop one bar of.
bar_phasePosition across the whole bar, [0, 1).The genuine bar phase, unlike bar.
balanceWhere the mix sits between the two channels: -1 hard left, 0 centred, +1 hard right.Absolute, never levelled — and 0 on any mono source, forever. See below.
spreadHow decorrelated the channels are: 0 identical, 0.5 fully decorrelated, 1 polarity-inverted.Absolute too. 0.5 means decorrelated, not “half wide”.
bass_balancebalance over the bass band alone.Same bands as bass/mid/treb. 0 when that band is silent.
mid_balancebalance over the mid band alone.The expressive one: hats thrown sideways while the bass stays centred.
treb_balancebalance over the treble band alone.
indexThe element’s own position in [0, 1] during a per-element evaluation.Not audio. 0 everywhere else — see below.
x / yThe vertex’s position in [0, 1] during a per-vertex evaluation; y = 0 is the top.Not audio. 0 outside a [per_vertex] table — see below.
radThat vertex’s distance from the centre, aspect-corrected against the render target.1.0 at the middle of the top and bottom edges on any display; further at the sides of a wide one.
angThat vertex’s angle from the centre, [0, tau), counter-clockwise from +x as you look at the screen.0 outside a [per_vertex] table.

The four headline levels are normalized (ADR-0049): each is divided by its own slowly-decaying running peak, with a silence floor so a quiet room reads 0 rather than amplified noise. That is what makes a threshold portable across tracks and gain staging. The cost is deliberate — absolute dynamics are hidden, so a quiet passage and a loud one read alike. When a look should scale with real loudness, use the *_raw twin and expect the old tiny magnitudes.

The five musical-time variables come from the beat tracker, and the three bar-position ones sit behind a confidence gate with a counter fallback, so they are always periodic and never confidently wrong about the music. 4/4 is assumed. None of the five is a dependable musical period. beat_index counts onset detections rather than beats, and the bar trio is the counter fallback most of the time — both measured, and diagnosed, in Musical time below. Read that section before you build structure on any of them.

tempo is the one variable that is not roughly 0–1. It is 0 until the tempo tracker warms up (the first several seconds of audio), then jumps to a real BPM in the ~60–200 range. Using it raw will blow out any parameter. Either scale it (tempo / 180) or — better — compare it:

select(tempo > 128, 2.5, 0.8) # a fast look above 128 BPM, a calm one below

novelty is experimental. It is a transient that spikes when the spectrum changes character — useful for gating an accent on a track or section change (beat * (novelty > 0.5)). Its DSP shape may change in a later release, or it may be withdrawn; do not build a preset that only works with today’s exact values.

The stereo field is absolute, and that is the whole design

balance, spread and the three per-band balances are the only variables here that are not divided by a running peak (ADR-0215). Every level is levelled, so bass > 0.5 means “loud for this track”; balance = 0 means centred, on every track, forever. Three consequences, and none of them is a bug to report:

  • A mono source reads 0 for all five, permanently. A mono file in foobar, a mono capture device, --signal chord or any other synthesized kind that predates pan: — all of them duplicate one buffer into both channels, and duplicated channels carry no position. A preset leaning on stereo is silently still on perfectly ordinary input.
  • Real music sits well inside ±0.3 of centre most of the time. Bind balance straight to a large visual move and the picture will look static and you will suspect the engine. Multiply up and clamp, exactly as you would with a *_raw level: clamp(balance * 3, -1, 1).
  • Levelling it would have been a lie you could not detect. Divided by a running peak, a centred mix’s noise floor stretches into confident wandering motion — convincing, and not in the music. Loudness is always present and only its scale is in question; position can be genuinely absent, and a normalizer cannot represent absence.

spread’s midpoint is the one number worth memorizing. 0.5 is fully decorrelated, not “half as wide as it gets”: 0 is two identical channels, 0.5 is two channels sharing nothing, and 1 is a polarity-inverted pair, which almost nothing but a test signal produces. A mono mix sits at 0; a wide one averages well below 0.5 and only touches the top of the range in moments — see the measured table below — so the useful gate is spread > 0.25 rather than anything near 1.

The field is published raw, per hop, with no smoother — the same choice the *_raw levels make. A hop is 10.7 ms, about one cycle of a low bass note, so spread in particular jitters on bass-heavy material. Ease it yourself with [smoothing]; a smoother inside the analyzer would be a second opinion you could not turn off.

To see what a source actually produces, every --signal / --audio filmstrip prints balance and spread rows beside the band rows (capturing), and --signal pan:<p>, wide:<seed> and split:<p> synthesize stereo on demand.

What real music reads, measured rather than guessed. Three 60-second clips of commercial tracks — a 2025 electronic score, a 1992 piano record, a 1991 rock record — plus a mono downmix of the first as a control, each about 5 100 analysis hops through --audio on 2026-09-19:

clipbalance min / mean / maxspread min / mean / max
electronic, 2025-0.390 / 0.024 / 0.4090.001 / 0.156 / 0.925
piano, 1992-0.536 / 0.001 / 0.6170.006 / 0.174 / 0.836
rock, 1991-0.510 / -0.018 / 0.4300.034 / 0.327 / 0.832
that electronic clip, downmixed to mono0.000 / 0.000 / 0.0000.000 / 0.000 / 0.000

Three readings come off that table, and each one changes how you bind the field.

  • The mean is within 0.03 of centre on every track while single hops reach ±0.4..±0.6. The excursions are the signal and the average is not, so multiply for the excursions: clamp(balance * 2.5, -1, 1) spends a full visual range on them without sitting on the rail.
  • spread averages 0.16..0.33 even on wide material, and a reading past 0.8 is a moment rather than a mix. spread > 0.25 is a sustained-wide gate, not a common one.
  • A hard pan carries no spread at all — one waveform at two gains is perfectly correlated, which is exactly what pan:<p> synthesizes. The two quantities are independent: gate colour or opacity on spread and you hide balance precisely where it is largest.

The same bindings were watched against live loopback rather than only against clips: a track with obvious stereo movement moves a balance-bound preset the way it sounds, and a mono one sits visibly still (ADR-0215).

Built from 13c7582 at version 0.158.0. This site tracks main and is not versioned per release.