Expand description
A tiny pure expression language over the audio-analysis variables, compiled once at preset load and evaluated per parameter per frame.
Grammar (recursive descent, standard precedence):
expr := sum (('>' | '<' | '>=' | '<=' | '==' | '!=') sum)*
sum := term (('+' | '-') term)*
term := unary (('*' | '/') unary)*
unary := ('-' | '+')? primary
primary:= number | ident | ident '(' expr (',' expr)* ')' | '(' expr ')'Comparisons sit at the lowest precedence and yield 1.0/0.0, so they
compose with arithmetic (0.4 + (bass > 0.2) * 0.3) and with select.
There are no boolean operators: with clean 0/1 results, min is and,
max is or, and 1 - c is not.
One thing an expression reads is not a function of this frame’s analysis:
a [latch] variable (ADR-0137). Its value is armed-and-fired state held in
the render layer and written into the reserved slots of Variables once
per preset per frame, before the params that read it. That leaves everything
here intact — evaluation is still a pure, re-entrant function of the bundle
it is handed, which is what lets one compiled expression run once per vertex
or once per element — while making the bundle depend on the frames before
it. A caller that runs no bank, and that is every probe and every
single-frame capture, reads a latch at its rest value of 0.
Variables: bass mid treb onset beat bar time tempo novelty index, the
per-vertex position x y rad ang, the
absolute-level escapes bass_raw mid_raw treb_raw onset_raw, and the musical
clock beat_index time_since_beat beat_in_bar bar_index bar_phase. The first
four are normalized against their own recent peak (ADR-0049), so a threshold
on them means “loud for this track” rather than naming a magnitude. bar is
beat phase under a historical name; bar_phase is the real thing
(ADR-0050).
Constants: pi tau.
Functions: sin cos abs floor sqrt log min max pow mod clamp lerp smoothstep select bin hash noise. Compilation is fallible (a malformed expression is
rejected with a surfaced error, never a panic); evaluation of a compiled
expression is total, panic-free, and allocation-free — it walks a prebuilt
AST returning f32, so it is safe to call every frame (hot-path §5).
bin(x) is the one function that reads something other than its arguments:
it samples the analysis frame’s log-spaced spectrum, which Variables
carries by borrow (ADR-0036). The language stays scalar-only — there is
no array type and no indexing syntax; the band array is reachable only
through this call, at a normalized position, interpolated.
hash(x) and noise(x) are the grammar’s only randomness (ADR-0051), and
they are random the way a shader is: pure functions of (argument, salt),
where the salt is a per-preset constant Variables carries. Nothing here
reads a clock or draws from an RNG — two evaluations of the same argument
under the same salt are bit-identical, which is exactly what NFR §6 asks of
visual randomness. Who supplies the salt is the preset’s business (see
schema::Preset); this module only mixes it in.
Structs§
- Expr
- A compiled expression: parse once,
evalevery frame. - Gate
Flag - A gate that a run never exercised, with the source text that names it.
- Observations
- Per-AST-node reachability accumulated across a run of probed evaluations
(ADR-0042). One of these belongs to one
Expr. - Variables
- A bound set of variable values for one evaluation. Field order matches
VAR_NAMES;beatis the caller’s bool coerced to 0.0/1.0.
Enums§
- Expr
Error - Why an expression failed to compile. Evaluation never errors.
- Gate
Kind - The four structural findings
Expr::flag_gatesreports. - Node
Observation - What one AST node did across a run.
Constants§
- LATCH_
CAP - How many
[latch]entries one preset may declare (ADR-0137). - SATURATED_
OCCUPANCY - Occupancy at or above which a
clamp()is reported asSaturated— the fraction of hops its inner value may spend pinned at the upper bound before the binding stops being a function of the audio and becomes a constant (ADR-0062). - VAR_
COUNT - Number of expression variables.
- VAR_
NAMES - The analysis variables an expression may reference, in slot order.
Functions§
- compile
- Compile a source expression into an evaluatable
Expr, with no latch names in scope. - compile_
with_ latches compile, with a preset’s[latch]names in scope (ADR-0137).- constant_
names - Every bare identifier that resolves to a literal, in declaration order.
- function_
names - Every built-in function name, in declaration order.
- is_
identifier - Whether
namelexes as a single identifier —[A-Za-z_][A-Za-z0-9_]*, the ruletokenizeapplies. - is_
reserved_ ident - Bare identifiers that resolve to a literal. Resolved before the variable
lookup so they cannot be shadowed; an unknown bare name still errors.
Whether
nameis already resolved by the grammar — a built-in variable (the reserved[latch]placeholders included), a named constant, or a function. - variable_
names - Every variable name an expression may write, in
VAR_NAMESorder.