Skip to content
Sample of SND Grid Sequencer (Multistability Pulse Grid)

audio_reactive · SNDGridSequencer

SND Grid Sequencer (Multistability Pulse Grid)

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. Cells fire when (tick + phase) mod inner_period == 0 (and not during an outer wrap), producing a synchronised pulse pattern reminiscent of the SND multislider sequencer. Beat rows are weighted higher (the SND kick / snare / hat channels). Visualisation: white-on-black minimal grid with a faint glow on each fire — the *sensate focus* pencil-tool aesthetic that Fell contrasted with his algorithmic solo work.

Original: https://sonicacts.com/archive/mark-fell

▶ 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
audio_reactive
Source
audio-reactive
Evolution
sequencer
Render
grid_pulse
Complexity
low
Agents
256
Year
2024
Author
Mark Fell (SND, with Mat Steel; solo; multistability algorithm)

Math essence

inner_period, outer_period, phase, outer_phase ∈ [inner_min..inner_max]^G×G. fire_mask = ((tick + phase) mod inner_period == 0) ∧ ¬((tick + outer_phase) mod outer_period == 0). energy[fire] = beat_boost[beat_rows]; energy[¬fire] *= 0.78. canvas[y0:y1, x0:x1] = fg_color * energy for each cell; 1-cell glow halo when energy > 0.25.

Parameters

Name Type Default Range Description
grid_size int 16 8–32 Side length of the square cell grid.
inner_min int 3 1–8 Minimum inner-loop period (in ticks).
inner_max int 13 4–32 Maximum inner-loop period (in ticks).
outer_min int 5 2–16 Minimum outer-loop period (in ticks).
outer_max int 31 8–64 Maximum outer-loop period (in ticks).
beat_rows tuple 0,4,8,12 — Row indices that get the beat boost (e.g. SND kick/snare/hat channels).
beat_boost float 1.6 0.5–4 Multiplier for beat-row cells.
cell_size int 22 10–48 Pixel size of each cell.
glow_radius int 1 0–4 Pixel halo around each fired cell.
bg_color tuple 8,8,12 — Background colour.
fg_color tuple 240,240,245 — Foreground colour.
seed int null 0–999999 RNG seed.

Reference

First 60 lines of reference.py. Full source: library_external/audio_reactive/SNDGridSequencer/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


class SNDGridSequencer:
    """Mark Fell / SND grid-sequencer aesthetic.

    A 16×16 grid where each cell has its own activation period
    (in ticks) and phase offset. Every step, a cell fires if
    ``(tick + phase) mod period == 0``, producing a synchronised
    pulse pattern reminiscent of the SND multislider sequencer
    (Fell's *Multistability* algorithm: nested inner/outer loops,
    impulse at each inner-loop wrap, phase-reset by the outer loop).
    Fired cells light up at their current "velocity" (the value
    computed by Mark Fell's two-loop accumulator: count from 0..1
    over inner-loop-length, snap-impulse on wrap). A handful of
    rows are weighted as "downbeats" with extra brightness, the
    way Fell pencils in kick / snare / hat channels.

    Visualisation is a white-on-black minimal grid with a faint
    outer glow on every fire — the *sensate focus* pencil-tool
    aesthetic that Fell contrasted with his algorithmic solo work.
    """

    family: ClassVar[str] = "audio_reactive"
    sketch: ClassVar[str] = "sndgridsequencer"

    def __init__(
        self,
        grid_size: int = 16,
        inner_min: int = 3,
        inner_max: int = 13,
        outer_min: int = 5,
        outer_max: int = 31,
        beat_rows: tuple[int, ...] = (0, 4, 8, 12),
        beat_boost: float = 1.6,
        cell_size: int = 22,
        glow_radius: int = 1,
        bg_color: tuple[int, int, int] = (8, 8, 12),
        fg_color: tuple[int, int, int] = (240, 240, 245),
        seed: int | None = None,
    ) -> None:
        self.grid_size = grid_size
        self.inner_min = inner_min
        self.inner_max = inner_max
        self.outer_min = outer_min
        self.outer_max = outer_max
        self.beat_rows = np.array(beat_rows, dtype=np.int32)
        self.beat_boost = beat_boost
        self.cell_size = cell_size
        self.glow_radius = glow_radius
        self.bg_color = np.array(bg_color, dtype=np.float32)
        self.fg_color = np.array(fg_color, dtype=np.float32)
        self._seed = seed
        self._tick = 0
        self.reset()

Try running it locally

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

python library_external/audio_reactive/SNDGridSequencer/reference.py

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

More from audio-reactive

See all audio_reactive artworks →