Track 5 — Waves and shapes

Everything so far distorts the feedback loop — the paint already on screen. Waves and shapes are the new ink laid on top each frame, before the loop's distortion is applied to it next time around. They're not a minor feature: 88% of the bundled catalog uses custom waves, and 99% uses custom shapes — this is the layer most presets draw with.

Lesson 1 · A second waveform

Every preset has one built-in waveform (wave_r/wave_g/wave_b, the one you've been coloring since Track 1). Custom waves are additional ones, up to eight, each fully independent:

wavecode_0_enabled=1
wavecode_0_samples=200
wavecode_0_scaling=1
wavecode_0_smoothing=0.5
wavecode_0_r=1
wavecode_0_g=0.7
wavecode_0_b=0.2
wavecode_0_a=1

▶ Run a static custom wave

wavecode_0_* are static parameters — enable it, give it 200 sample points and an amber color. On its own it draws the audio waveform again, just as a second colored line. The interesting part is next.

Lesson 2 · Shaping every sample point

wave_N_per_point equations run once per sample point of the wave — the finest-grained code in the whole language, potentially hundreds of times a frame for one wave:

wave_0_per_point1=t=sample*6.283185+time*0.3;
wave_0_per_point2=x=0.5+0.3*sin(t*3)*(1+0.3*value);
wave_0_per_point3=y=0.5+0.3*cos(t*2)*(1+0.3*value);

▶ Run the Lissajous wave

The two inputs unique to this context:

You must set x/y yourself here — nothing else positions the point. This is the fundamental deal with per-point code: total control over where every point of the wave lands, in exchange for writing the geometry from scratch.

Lesson 3 · A shape, sitting still

Custom shapes (up to four, each with 3–100 sides and up to 1024 instances) are the other half of this layer — solid polygons instead of lines:

shapecode_0_enabled=1
shapecode_0_sides=5
shapecode_0_thickoutline=1
shapecode_0_x=0.5
shapecode_0_y=0.5
shapecode_0_rad=0.15
shapecode_0_r=0.9
shapecode_0_g=0.6
shapecode_0_b=0.1

▶ Run a static pentagon

Static params only — the pentagon just sits there. shapecode_0_* mirrors wavecode_0_*: _enabled, geometry (sides, x, y, rad, ang), and color (r/g/b/a).

Lesson 4 · Giving a shape a per_frame

shape_N_per_frame runs once per frame for that shape instance — the same rhythm as the root per_frame, just scoped to one shape:

shape_0_per_frame1=x=0.5+0.25*sin(time*0.7);
shape_0_per_frame2=y=0.5+0.25*cos(time*0.7);
shape_0_per_frame3=ang=time*0.7;

▶ Run the orbiting pentagon

Nothing new mechanically — this is Track 1's sin(time) heartbeat, just steering a shape's position instead of a screen-wide knob. shape_N_init (unused here) runs once, the first frame only, for one-time setup.

Lesson 5 · Morphing instead of moving

A shape doesn't have to move to be alive — it can change identity entirely, frame by frame. Pattern 12 from the coding guide:

shape_0_per_frame1=s=frame%6+4;
shape_0_per_frame2=sides=s;
shape_0_per_frame3=rad=0.08+s*0.01;
shape_0_per_frame4=ang=s*0.3;
shape_0_per_frame5=r=sin(s*1.1)*0.5+0.5;
shape_0_per_frame6=g=sin(s*2.2)*0.5+0.5;
shape_0_per_frame7=b=sin(s*3.3)*0.5+0.5;

▶ Run the shape state machine

frame%6+4 cycles s through 4, 5, 6, 7, 8, 9, 4, 5, … — one step every frame. Every other line reads that same s: sides count, radius, rotation, and all three color channels are just different functions of it. The shape isn't animating a fixed pentagon — it's cycling through six entirely different polygon identities, each with its own look, six times a second at 36fps-equivalent stepping. This is the technique behind shapes that seem to "breathe" between forms rather than move.

Lesson 6 · Wired to the music

Everything in this track has run on time alone. Bridge it to audio exactly the way Track 4 did — smooth in per_frame, write a q-var, read it wherever it's needed:

per_frame_1=ra=6/fps;
per_frame_2=bass_avg=bass_avg*(1-ra)+ra*bass;
per_frame_3=q8=bass_avg;
wave_0_per_point1=t=sample*6.283185+time*0.3;
wave_0_per_point2=x=0.5+(0.2+0.15*q8)*sin(t*3);
wave_0_per_point3=y=0.5+(0.2+0.15*q8)*cos(t*2);
shape_0_per_frame1=rad=0.1+q8*0.15;
shape_0_per_frame2=ang=time*0.5;

▶ Run the reactive wave and shape

q8 is computed exactly once, in the root per_frame, and both the wave's per-point code and the shape's per-frame code read the same value that frame. This is the general answer to "how do waves/shapes hear the music": they don't read audio directly — per_frame does the listening (Track 3), and everything downstream just reads the result.

What you can now build

Waves and shapes are how a preset draws something recognizable rather than just distorting a blur — lines that trace curves, polygons that orbit or morph, both wired into the same audio pipeline as everything else. Between Tracks 1–5, you can now read the per_frame/per_pixel/wave/shape portion of almost any preset in the catalog.

Next: Track 6 — Shaders, the one piece left: the GLSL warp_shader/comp_shader pair that 64% of modern presets use for the effects equations alone can't reach.