live_coding_synth · TopolecturesOliviaJack
Topolectures (Olivia Jack) — 2D cell grid + text snippets + audio-amplitude pulse
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. The pulse combines a per-cell sin chain (cell_freq, phase) with a 1 Hz kick impulse and a low/mid/high band amplitude (the performer's speech amplitude in the live Topolectures piece). The default grid is 16×16 with a 14-px cell, 480×480 canvas. A small 5×7 pixel font is rasterised into a numpy bitmap for each cell and composited onto the canvas at the per-cell brightness.
Original: https://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
Per cell (r, c): phase, cell_freq ∈ rand; amp = audio_low(t) + audio_mid(t) + audio_high(t) + 1Hz_kick(t). bright(r,c,t) = clip(0.5 + 0.4*sin(t * amp_freq * cell_freq + phase * phase_jitter) + 0.5*kick_pulse + 0.25*amp, 0, 1). canvas[y0:y1,x0:x1] = max(canvas[y0:y1,x0:x1], fg_color * bright * glyph_bitmap[word]).
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 480 | 240–720 | Output side length in pixels (HxW). |
grid_size | int | 16 | 4–32 | Side length of the cell grid (N×N). |
cell_size | int | 14 | 8–32 | Pixel size of each cell (square). |
n_glyphs | int | 2 | 1–4 | Max number of glyphs per cell (1 or 2 looks best). |
amp_freq | float | 0.13 | 0.02–1 | Time-frequency of the per-cell brightness sin chain. |
phase_jitter | float | 0.6 | 0–2 | How much the random per-cell phase enters the brightness equation. |
low_freq | float | 0.7 | 0.1–4 | Audio low-band frequency (synthetic). |
mid_freq | float | 1.7 | 0.1–4 | Audio mid-band frequency (synthetic). |
high_freq | float | 2.9 | 0.1–4 | Audio high-band frequency (synthetic). |
kick_freq | float | 1 | 0.1–4 | 1-Hz-like speech-rhythm kick frequency (per Olivia Jack's live Topolectures). |
kick_strength | float | 0.7 | 0–2 | Strength of the kick impulse on every cell. |
bg_color | tuple | 10,12,18 | — | Background colour. |
fg_color | tuple | 220,230,255 | — | Foreground (text) colour. |
seed | int | null | 0–999999 | RNG seed (cell text + phase + cell_freq). |
Reference
First 60 lines of reference.py. Full source:
library_external/live_coding_synth/TopolecturesOliviaJack/reference.py
"""TopolecturesOliviaJack — Olivia Jack's 2D cell-grid + text snippets.
Topolectures (Olivia Jack) is a 2D grid of small cells. Each cell
displays a tiny snippet of text (one or two characters), and the
brightness of each cell pulses with an audio-amplitude signal —
synthetic here, but the structure matches the live-coding
performance: the performer reads aloud, the cell whose text
matches what is being said lights up, the rest stay dim.
The visual is built by rasterising each cell's text glyph into a
small bitmap (numpy), then compositing it onto the canvas with a
per-cell brightness multiplier that tracks a per-cell sin chain
whose phase is randomised at reset. A 1 Hz kick impulse (the
audio amplitude envelope) brightens every cell briefly so the
whole grid breathes in time with the speech rhythm.
Cell-text is sampled from a corpus of words associated with
topology / topolectures ("sheaf", "locale", "frame", "open",
"closed", "cover", "limit", "point", "net", "filter", ...). The
default cell size is 14×14 px and the default grid is 16×16, so
the rendered canvas is 240×240. Two-character cells (e.g. "≤",
"id", "~") are drawn as two 7×14 bitmaps stitched side-by-side.
"""
from __future__ import annotations
from typing import ClassVar
import numpy as np
_CORPUS: tuple[str, ...] = (
"sheaf", "locale", "frame", "open", "closed", "cover",
"limit", "point", "net", "filter", "basis", "ideal",
"prime", "ring", "mod", "field", "topos", "yoneda",
"etale", "sieve", "germ", "stalk", "space", "chart",
"atlas", "sheaf", "gluing", "flabby", "injective",
"kernel", "image", "rank", "trace", "spec", "scheme",
"stack", "gerbe", "torsor", "lie", "group", "algebra",
"module", "tensor", "hom", "ext", "tor", "der",
"diff", "conn", "curv", "tors", "geod", "chart",
"~", "id", "Δ", "≤", "≥", "→", "↦", "≅", "⊂", "⊃", "∧", "∨", "¬", "∀", "∃",
"∞", "∑", "∏", "∂", "∇", "∈", "∉", "∋", "∅", "η", "π", "λ", "μ", "σ", "φ",
)
# ---------------------------------------------------------------------------
# 5x7 pixel font for ASCII printable + a few unicode glyphs
# ---------------------------------------------------------------------------
_FONT_5x7: dict[str, tuple[str, ...]] = {
"A": ("01110", "10001", "10001", "11111", "10001", "10001", "10001"),
"B": ("11110", "10001", "10001", "11110", "10001", "10001", "11110"),
"C": ("01110", "10001", "10000", "10000", "10000", "10001", "01110"),
"D": ("11110", "10001", "10001", "10001", "10001", "10001", "11110"),
"E": ("11111", "10000", "10000", "11110", "10000", "10000", "11111"),
"F": ("11111", "10000", "10000", "11110", "10000", "10000", "10000"),
"G": ("01110", "10001", "10000", "10111", "10001", "10001", "01110"),
"H": ("10001", "10001", "10001", "11111", "10001", "10001", "10001"),
"I": ("11111", "00100", "00100", "00100", "00100", "00100", "11111"), Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/live_coding_synth/TopolecturesOliviaJack/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from live_coding_synth
Hydra Video Synth (numpy port of Olivia Jack's Hydra)
live_coding_synth · HydraVisualSynth
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).
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.