live_coding_synth · HydraVisualSynth
Hydra Video Synth (numpy port of Olivia Jack's Hydra)
A pure-numpy port of the core Hydra video-synth API: chains of sources (osc, noise, shape, gradient, solid, voronoi) composed with geometry modifiers (rotate, scale, scroll, kaleid, pixelate, repeat) and color/blend modifiers (invert, posterize, thresh, color, brightness, contrast, luma, saturate, hue, add, diff, mult, blend) — including the signature modulate operator a.modulate(b, scale), which uses b's red and green channels to displace a's x and y coordinates (with modulateRotate, modulateScale, modulatePixelate, modulateKaleid variants). The chain string is parsed into a small AST and evaluated on a low-trail canvas; set_chain() lets a viewer 'live-code' by swapping the chain and calling step() again — the same edit-and-rerun loop that defines a Hydra session.
Original: https://hydra.ojack.xyz
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
chain := source (mod)* ; source in {solid, gradient, osc, noise, shape, voronoi} ; mod in {rotate, scale, scroll, kaleid, pixelate, repeat, invert, posterize, thresh, color, brightness, contrast, luma, saturate, hue, add, diff, mult, blend, modulate, modulateRotate, modulateScale, modulatePixelate, modulateKaleid}. modulate(b, k): resample a at uv + k * (b.r, b.g). canvas <- trail*canvas + (1-trail)*bg + eval(chain).
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 320 | 128–640 | Output side length in pixels (HxW). |
chain | str | osc(20, 0.1, 0.8).rotate(0.05).modulate(noise(3, 0.1).rotate(0.1), 0.5).modulate(osc(8).kaleid(4), 0.3) | — | Hydra-style chain string (sources composed with .modifiers). |
trail | float | 0.88 | 0–0.99 | Per-step canvas persistence (1.0 = no trail, 0.0 = full clear). |
bg_color | tuple | 8,6,14 | — | Background colour mixed in at (1-trail) per step. |
seed | int | null | 0–999999 | RNG seed (reserved for stochastic sources). |
Reference
First 60 lines of reference.py. Full source:
library_external/live_coding_synth/HydraVisualSynth/reference.py
"""HydraVisualSynth — Olivia Jack's Hydra video synth in pure numpy.
A small, faithful subset of the Hydra API
(`https://hydra.ojack.xyz`) ported to numpy arrays so the same
chained-function live-coding aesthetics can be rendered from a
deterministic seed:
osc(freq, sync, offset) # source: visual oscillator (sin-based)
noise(scale, offset) # source: hash-based pseudo-Perlin
shape(sides, radius, smooth) # source: regular polygon SDF
gradient(speed) # source: 3-channel horizontal gradient
solid(r, g, b) # source: solid colour
voronoi(scale, speed, blend) # source: Voronoi cells
.rotate(theta) # geometry: rotate uv around centre
.scale(s) # geometry: scale uv around centre
.scroll(x, y) # geometry: pan uv
.kaleid(n) # geometry: kaleidoscope fold
.pixelate(p, smooth) # geometry: posterise uv
.repeat(x, y) # geometry: tile
.modulate(src, amount) # modulate: src.r → x warp,
# src.g → y warp
.modulateRotate(src, amount) # modulate: src.r,g → θ(x,y)
.modulateScale(src, amount) # modulate: src.r → scale warp
.modulatePixelate(src, range_) # modulate: src.r → pixelate amount
.modulateKaleid(src, range_) # modulate: src.r → kaleid fold count
.add(src), .diff(src), .mult(src), .blend(src)
# blend: arithmetic on RGB
The composition `osc(40).modulate(noise().rotate(0.1), 0.5).out()`
becomes ``hydra.evaluate("osc(40).modulate(noise().rotate(0.1), 0.5)")``.
A built-in operator chain can be edited at run-time with
``set_chain("osc(10, 0.1).rotate(0.1).kaleid(4).modulate(noise(3), 0.5)")``
so a viewer can "live-code" by swapping the chain string and calling
``step()`` again. The chain is parsed into an AST, evaluated against
the source dictionary, and composited onto a low-trail canvas so the
visual keeps an evolving ghost of past frames.
"""
from __future__ import annotations
import re
from dataclasses import dataclass, field
from typing import Any, Callable, ClassVar
import numpy as np
# ---------------------------------------------------------------------------
# Sources
# ---------------------------------------------------------------------------
def src_solid(canvas: np.ndarray, r: float, g: float, b: float) -> np.ndarray:
h, w, _ = canvas.shape
out = np.zeros((h, w, 3), dtype=np.float32)
out[..., 0] = np.float32(r)
out[..., 1] = np.float32(g)
out[..., 2] = np.float32(b) Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/live_coding_synth/HydraVisualSynth/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from live_coding_synth
P5Live sin/cos Spirograph Sketch
live_coding_synth · P5LiveSketch
A pure-numpy port of the canonical p5.js sin/cos live-coding sketch: a spirograph-like cloud of points whose polar coordinates are themselves nested sin/cos chains.
Strudel 16-Step Pattern Visualiser (4x4 grid of sample-typed shapes)
live_coding_synth · StrudelVisualizer
A pure-numpy port of Strudel's signature 4×4 (16-step) pattern grid.
TidalCycles Mini-Notation Pattern Visualiser
live_coding_synth · TidalCyclesPattern
A pure-numpy port of TidalCycles' rhythm mini-notation, expanded per cycle into a row of (sample, variant) tuples and visualised as a row of pulsing shapes that scroll horizontally.
Topolectures (Olivia Jack) — 2D cell grid + text snippets + audio-amplitude pulse
live_coding_synth · TopolecturesOliviaJack
A pure-numpy port of Olivia Jack's Topolectures: a 2D grid of cells, each cell holding a 1–2 character text snippet from a topology-mathematics corpus (sheaf, locale, frame, open, closed, cover, limit, point, net, filter, basis, ideal, prime, ring, mod, field, topos, yoneda, etale, sieve, …) and brightness pulsed by a synthetic audio-amplitude signal.