Skip to content
Sample of Strudel 16-Step Pattern Visualiser (4x4 grid of sample-typed shapes)

live_coding_synth · StrudelVisualizer

Strudel 16-Step Pattern Visualiser (4x4 grid of sample-typed shapes)

A pure-numpy port of Strudel's signature 4×4 (16-step) pattern grid. A Tidal mini-notation pattern is parsed to exactly 16 events per cycle, then each event is drawn as a sample-typed shape in a 4×4 grid: kick/bd → red filled disc + glow ring; snare/sn → yellow square + centre dot; hi-hat/hh → cyan X-mark; clap/cp → violet diamond; bass → green bar (size = note value); pad/chord/lead → coloured bar; rest (~) → empty cell with a thin gridline. A playback cursor (4 ticks per step) sweeps column-by-column on a per-cycle clock — the same playhead you see in a Strudel REPL. The default pattern is bd*4, ~ sn ~ hh*2, cp*4, bd*2 hh*2 — a four-channel drum-machine polyrhythm exactly like the multi-channel patterns Felix Roos writes in Strudel live-coding sets.

Original: https://strudel.cc

▶ 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.

Family
live_coding_synth
Source
live_coding_synth
Evolution
pattern
Render
4x4_pattern_grid
Complexity
medium
Agents
16
Year
2024
Author
Felix Roos / TidalCycles Strudel team (JS port of TidalCycles)

Math essence

parse(pattern) -> steps[16] of (sample, variant). For each step s_i in 0..15: (r, c) = (s_i // 4, s_i % 4); cx,cy = margin + c*cs + cs*0.5. shape(sample): bd -> disc(0.30*cs); sn -> square(0.85*0.30*cs); hh -> X-mark(0.30*cs); cp -> diamond(0.30*cs); bass/lead -> bar(0.30*cs, 0.6 + 0.4*v/8); ~ -> dot(0.04*cs). active_step = (tick // 4) % 16; draw cursor rectangle in (250, 220, 140). canvas[y0:y1,x0:x1] = max(canvas, ink).

Parameters

Name Type Default Range Description
dim int 480 256–720 Output side length in pixels (HxW).
pattern str bd*4, ~ sn ~ hh*2, cp*4, bd*2 hh*2 — Tidal/Strudel mini-notation pattern. Supports sample names, ~ rest, [ ] group, *N repeat, /N slow, :N variant, , parallel.
n_steps int 16 8–32 Number of events per cycle (default 16 for the canonical Strudel 4x4 grid).
cell_size int 100 60–180 Pixel size of each cell (square).
bg_color tuple 8,10,16 — Background colour.
grid_color tuple 40,40,50 — Cell gridline colour.
seed int null 0–999999 RNG seed (reserved).

Reference

First 60 lines of reference.py. Full source: library_external/live_coding_synth/StrudelVisualizer/reference.py

"""StrudelVisualizer — Strudel's 16-step pattern as a 4x4 grid of shapes.

Strudel (https://strudel.cc) is the JavaScript port of TidalCycles
by Felix Roos and the tidalcycles/strudel team — the same
mini-notation (``bd*4, hh*8, ~ sn``) but running live in the
browser. Strudel's signature visualisation is a 4×4 (16-step)
grid of "events" — each cell shows the sample name, an icon
(Drum, Note, Chord, Rest), and a brightness driven by the
event's `gain` / `velocity`.

This module renders the same 4×4 grid in pure numpy:

* parses a Strudel-style mini-notation pattern (full Tidal
  subset — `bd`, `~`, `[ ]`, `*N`, `/N`, `:N`, `< >`, `,`);
* flattens it to exactly 16 events per cycle (the canonical
  16-step Strudel cycle);
* draws each event as a small shape in a 4×4 grid:
  - kick / bd       → red filled disc + glow ring
  - snare / sn      → yellow square + glow ring
  - hi-hat / hh     → cyan X-mark
  - clap / cp       → violet diamond
  - bass note       → green bar (size = note value)
  - chord           → 3-stacked triangle
  - rest (`~`)      → empty cell with thin gridline
  - other           → small white ring

A playback cursor (the active step) sweeps column-by-column on
a per-cycle clock — the same "playhead" you see in a Strudel
REPL. Per-step gain modulates each cell's brightness.
"""

from __future__ import annotations

import re
from dataclasses import dataclass
from typing import ClassVar

import numpy as np


_DRUM_HUE: dict[str, tuple[int, int, int]] = {
    "bd": (240, 70, 80),
    "sd": (250, 220, 110),
    "sn": (250, 220, 110),
    "hh": (130, 230, 250),
    "cp": (180, 120, 250),
    "lt": (180, 250, 180),
    "mt": (250, 180, 200),
    "ht": (250, 130, 80),
    "cb": (250, 130, 80),
    "rim": (210, 200, 240),
    "arpy": (140, 220, 180),
    "arps": (140, 220, 180),
    "bass": (160, 250, 200),
    "lead": (255, 200, 240),
    "pad": (130, 180, 255),
    "stab": (255, 220, 130),
    "chord": (255, 220, 130),
}

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/live_coding_synth/StrudelVisualizer/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from live_coding_synth

Sample of Hydra Video Synth (numpy port of Olivia Jack's Hydra)

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).

View →
Sample of P5Live sin/cos Spirograph Sketch

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.

View →
Sample of TidalCycles Mini-Notation Pattern Visualiser

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.

View →
Sample of Topolectures (Olivia Jack) — 2D cell grid + text snippets + audio-amplitude pulse

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.

View →

See all live_coding_synth artworks →