audio_reactive · IkedaGridMatrix
data.matrix Glitch Grid (Binary Cellular Automaton + Beat Faders)
A 32×32 binary cell grid plus a thin frame of beat-fader bars around the edges. Per step, the grid evolves via a Game-of-Life-like cellular automaton (live cell survives with 2 or 3 neighbours, dead cell born with 3), with random glitch-bit-flips and occasional full inversions — the glitch-aesthetic Ikeda uses in *datamatics* and *data.matrix*. A sin-chain beat signal drives the fader-bar heights (low / mid / high band magnitudes), and a faint noise floor washes the canvas. The cell grid itself nods to the *matrix [for rooms]* CD track listing (0000000001, 0000000010, ...): Ikeda's piece is literally a binary matrix.
Original: https://www.ryojiikeda.com/project/matrix/
▶ 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
state[i,j] ∈ {0,1}^G×G. neighbour_count = Σ state shifted in 8 directions. next = (state ∧ (n ∈ {2,3})) ∨ (¬state ∧ (n == 3)). glitch_mask = random < glitch_rate; flip_mask = random < 0.5; next = where(glitch_mask, flip_mask, next). if random < invert_rate: next = 1 - next. fader_bar[i] = |sin(2π*(0.4 + 0.13 i) * t + 0.7 i) + 0.6 beat|. canvas[y0:y1, x0:x1] = fg_color * state[r, c]; faint noise floor += random * noise_floor * 255.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
grid_size | int | 32 | 8–64 | Side length of the square cell grid. |
cell_px | int | 14 | 6–32 | Pixel size of each cell. |
glitch_rate | float | 0.04 | 0–0.3 | Per-cell probability of random glitch-bit-flip. |
invert_rate | float | 0.02 | 0–0.2 | Per-step probability of full grid inversion. |
fader_bars | int | 8 | 0–32 | Number of beat-fader bars along top + bottom edges. |
fader_height | int | 10 | 2–24 | Pixel height of the fader-bar frame. |
noise_floor | float | 0.04 | 0–0.4 | Per-pixel white-noise wash intensity (Ikeda glitch floor). |
beat_freq | tuple | 0.7,1.4,2.1,3 | — | Beat sin-chain frequencies. |
beat_amp | tuple | 0.2,0.18,0.14,0.1 | — | Beat sin-chain amplitudes. |
fg_color | tuple | 240,240,240 | — | Foreground colour. |
bg_color | tuple | 0,0,0 | — | Background colour. |
seed | int | null | 0–999999 | RNG seed. |
Reference
First 60 lines of reference.py. Full source:
library_external/audio_reactive/IkedaGridMatrix/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
class IkedaGridMatrix:
"""Ryoji Ikeda's grid-matrix aesthetic.
A high-contrast binary cell grid (default 32×32) plus a thin
"frame" of fader bars around the edges. Per step, the grid
evolves via cellular-automaton-like state transitions with
random glitch inversions, then the active cells are binarised
(white-on-black) and the canvas is washed with the glitch
white-noise floor that Ikeda uses in *datamatics* and
*data.matrix*. The faint per-row numerical readout (binary
strings) is a direct nod to the *matrix [for rooms]* CD
track listing (0000000001, 0000000010, ...) — Ikeda's piece
is literally a binary matrix.
"""
family: ClassVar[str] = "audio_reactive"
sketch: ClassVar[str] = "ikedagridmatrix"
def __init__(
self,
grid_size: int = 32,
cell_px: int = 14,
glitch_rate: float = 0.04,
invert_rate: float = 0.02,
fader_bars: int = 8,
fader_height: int = 10,
noise_floor: float = 0.04,
beat_freq: tuple[float, ...] = (0.7, 1.4, 2.1, 3.0),
beat_amp: tuple[float, ...] = (0.20, 0.18, 0.14, 0.10),
fg_color: tuple[int, int, int] = (240, 240, 240),
bg_color: tuple[int, int, int] = (0, 0, 0),
seed: int | None = None,
) -> None:
self.grid_size = grid_size
self.cell_px = cell_px
self.glitch_rate = glitch_rate
self.invert_rate = invert_rate
self.fader_bars = fader_bars
self.fader_height = fader_height
self.noise_floor = noise_floor
self.beat_freq = np.array(beat_freq, dtype=np.float32)
self.beat_amp = np.array(beat_amp, dtype=np.float32)
self.fg_color = np.array(fg_color, dtype=np.float32)
self.bg_color = np.array(bg_color, dtype=np.float32)
self._seed = seed
self._t = 0.0
self._tick = 0
self._last_beat = 0.0
self._phase = np.array([], dtype=np.float32)
self.reset()
def reset(self, seed: int | None = None) -> None:
if seed is not None: Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/audio_reactive/IkedaGridMatrix/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from audio-reactive
Daily Sketch Curve Morph (Synthetic Gesture)
audio_reactive · LiebermanDailySketch
A parametric polar / hypotrochoid curve whose three radii (R, r, d) are continuously morphed by independent sin-wave chains — Zach Lieberman's signature 'use mathematical functions like sin() and tan() in place of randomness' rule from his Daily Sketches project.
FFT-Spectrum Particle Field (Synthetic Audio)
audio_reactive · PasmaFFTSpectrum
A particle field whose velocity is driven by three FFT-magnitude bands (low / mid / high) computed from a sliding window of synthetic audio.
Reactive Concentric Rings (FFT-Band-Driven)
audio_reactive · PasmaReactiveCircle
N concentric rings around the canvas centre, each driven by a different FFT band (low / mid / high).
SND Grid Sequencer (Multistability Pulse Grid)
audio_reactive · SNDGridSequencer
A 16×16 grid where each cell has its own activation period (inner-loop ticks) and phase offset, modelled after Mark Fell's *Multistability* algorithm: nested inner/outer loops, impulse at each inner-loop wrap, phase-reset by the outer loop.