Skip to content
Sample of Sound-Reactive Particle Field (Synthetic Audio)

toxi_openframeworks · SoundReactiveField

Sound-Reactive Particle Field (Synthetic Audio)

Particles advected by a force field whose horizontal component is driven by a synthetic audio signal: a chain of N sinusoids at different frequencies/amplitudes (the 'audio'), with the audio's instantaneous value plus its time derivative ('beat onset') driving the field. The vertical component is a slow baseline oscillator. Particles leave low-alpha strokes on a fading canvas, producing the iconic oF audio-reactive aesthetic (Nick Hardeman's audio visualizer, Anthony Scavarelli's interactive visualizer).

Original: https://openframeworks.cc/ofBook/chapters/sound.html

▶ 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
toxi_openframeworks
Source
toxi · openFrameworks
Evolution
particle
Render
trail_accumulation
Complexity
medium
Agents
1200
Year
2011
Author
openFrameworks community (Hardeman, Scavarelli, ofBook 'Sound')

Math essence

audio(t) = Σ amp_i * sin(2π freq_i t + phase_i). Field_x = field_strength * audio + beat_gain * d(audio)/dt, Field_y = slow baseline oscillator. Velocity update with max_speed clamp. Canvas *= trail_decay, then add ink * 0.10 at each particle position. Hue rotates by hue_shift per step.

Parameters

Name Type Default Range Description
dim int 400 200–1000 Square canvas side length in pixels.
num_particles int 1200 200–4000 Particle count.
num_bands int 5 1–8 Number of sinusoid bands in the synthetic audio chain.
band_freqs tuple 0.42,0.97,1.7,2.5,3.3 — Per-band frequencies (Hz) of the synthetic audio.
band_amps tuple 0.6,0.45,0.35,0.25,0.2 — Per-band amplitudes.
field_strength float 2.4 0.1–8 Gain applied to the audio-driven field component.
beat_gain float 4 0–12 Gain applied to the audio derivative (transient / beat onset) component.
max_speed float 4.5 0.5–12 Speed clamp (px/frame).
trail_decay float 0.965 0.7–0.999 Per-frame multiplicative fade of the canvas.
hue_shift float 0.012 0–0.1 Hue rotation per step (turns).
bg_color tuple 8,10,18 — Background colour.
seed int null 0–999999 RNG seed.

Reference

First 60 lines of reference.py. Full source: library_external/toxi_openframeworks/SoundReactiveField/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


class SoundReactiveField:
    """Sound-reactive particle field driven by a synthetic audio chain.

    A bank of N sinusoids acts as the "audio signal":

        audio(t) = Σ_i  amp_i * sin(2π freq_i t + phase_i)

    The instantaneous magnitude of this sum (and its derivative,
    treated as a beat-onset detector) drives a horizontal force field
    across the canvas. Particles feel this field, drift in the
    direction of the force, and leave a low-alpha trail on a fading
    canvas — the iconic look of openFrameworks audio-reactive
    visuals (Nick Hardeman, Anthony Scavarelli, and the `oF` chapter
    in the ofBook's *Sound* section all use this same skeleton).
    """

    family: ClassVar[str] = "toxi_openframeworks"
    sketch: ClassVar[str] = "soundreactivefield"

    def __init__(
        self,
        dim: int = 400,
        num_particles: int = 1200,
        num_bands: int = 5,
        band_freqs: tuple[float, ...] = (0.42, 0.97, 1.7, 2.5, 3.3),
        band_amps: tuple[float, ...] = (0.6, 0.45, 0.35, 0.25, 0.2),
        field_strength: float = 2.4,
        beat_gain: float = 4.0,
        max_speed: float = 4.5,
        trail_decay: float = 0.965,
        hue_shift: float = 0.012,
        bg_color: tuple[int, int, int] = (8, 10, 18),
        seed: int | None = None,
    ) -> None:
        self.dim = dim
        self.num_particles = num_particles
        self.num_bands = num_bands
        self.band_freqs = np.array(band_freqs, dtype=np.float32)
        self.band_amps = np.array(band_amps, dtype=np.float32)
        self.field_strength = field_strength
        self.beat_gain = beat_gain
        self.max_speed = max_speed
        self.trail_decay = trail_decay
        self.hue_shift = hue_shift
        self.bg_color = np.array(bg_color, dtype=np.float32)
        self._seed = seed
        self._t = 0.0
        self._last_audio = 0.0
        self._hue = self.rng.integers(0, 360) if False else 0
        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/toxi_openframeworks/SoundReactiveField/reference.py

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

More from toxi · openFrameworks

Sample of Generative Type Letterforms

Generative Type Letterforms

toxi_openframeworks · GenerativeTypeLetterforms

Letterforms assembled from a 9×9 stroke grid alphabet (A–Z subset), then modulated by a parametric function (bar widths and stroke positions follow `a * sin(b*x + c)` style curves) and optionally recursively subdivided into smaller marks.

View →
Sample of Gray-Scott Reaction-Diffusion

Gray-Scott Reaction-Diffusion

toxi_openframeworks · ReactionDiffusionGS

The canonical two-species Gray-Scott reaction-diffusion model on a periodic square grid: dU/dt = Du*lap(U) - U*V^2 + F*(1-U), dV/dt = Dv*lap(V) + U*V^2 - (F+k)*V.

View →
Sample of Median-Cut Color Quantizer

Median-Cut Color Quantizer

toxi_openframeworks · ColorQuantizer

Heckbert's 1982 median-cut color quantization applied to an evolving procedural gradient + low-resolution noise wash.

View →
Sample of Pixel Sort (Glitch Art)

Pixel Sort (Glitch Art)

toxi_openframeworks · PixelSort

Per-row pixel sorting à la Kim Asendorf's `ASDFPixelSort` and Karsten Schmidt's own glitch-art Processing sketches.

View →
Sample of Verlet Particle-Spring Network

Verlet Particle-Spring Network

toxi_openframeworks · ParticleSpring2D

A Verlet-integrated particle network connected to its k-nearest neighbours by Hooke's-law springs.

View →
Sample of Voronoi Tessellation with Lloyd Relaxation

Voronoi Tessellation with Lloyd Relaxation

toxi_openframeworks · VoronoiRelaxation

Lloyd's algorithm applied to a jittered point cloud: each seed is replaced with the centroid of its Voronoi cell, repeatedly, producing ever-more-uniform polygonal cells.

View →

See all toxi_openframeworks artworks →