By the numbers

4
live species: Seed, Flowers, Mold, Bacteria
5
ecological controls shared by every species
19
validation gates on every build, plus the browser harness in CI
12 ms
from noteOn to audible, measured in Chromium and WebKit
Product brief
The Plantasia Sound Engine makes sound that lives. A traditional preset captures one moment: oscillator, filter, effect levels. A Sound World describes how a sound is born, blooms, decays, and moves, and the engine plays it as a generative organism rather than recalling a snapshot.
It is a library for instrument apps. A host initializes it on a user gesture, loads a species or a preset, and drives it with five ecological controls, notes, or MIDI. Every musical event comes back out on a typed bus stamped with audio clock time, and a per frame analysis of the master bus gives the host bands, centroid, and onsets, so visuals can follow the sound without their own FFT.
It is part of the Plantasonic ecosystem and stands on its own. Each Sound World carries its own visual identity, a theme, palette, motion style, intensity, and tempo that host apps render however they like, and the control surface ships its own waveform and level visualizers. No other engine is involved.

4
live species: Seed, Flowers, Mold, Bacteria
5
ecological controls shared by every species
19
validation gates on every build, plus the browser harness in CI
12 ms
from noteOn to audible, measured in Chromium and WebKit
I designed and built the engine: the Sound World concept and the four archetypes, the species plugin architecture and registry, the ecological control layer, the generative and performance engines, the lifecycle contract, the event bus, the master bus and audio analysis, the scheduler and MIDI scaffold, the host facade and Plantasonic adapter, the demo control surface, the browser performance harness and its CI job, the modulation engine and its species hook, the snapshot and morph layer, the lab page for tuning by ear, and the eighteen validation gates and documentation that hold it together.
Role
Designer, Engineer, Sound Designer
Timeframe
2026
Disciplines
Sound Design, Systems Design, Library API Design
Version 1.2.1, released September 2026. 1.2.0 came three days after 1.0.0 froze the public tier and 1.1.0 added modulation; 1.2.1 is the simplicity release: no engine change, but the surface folded so what a host reads first is the seven methods a player feels, the demo opening on those seven with save and recall, and six lines to the first sound measured on every build. 1.2 is hardening and state: getSnapshot and applySnapshot carry the whole host facing state (species, controls, tempo, routes, preferences, polyphony cap) as one JSON object, with a timed morph between two that crosses a species switch; a polyphony cap for phones; MIDI input select; the Playwright harness running in GitHub Actions in Chromium and WebKit; a bundle size gate; Tone.js pinned; and the v1 preset path deprecated for removal at 2.0. Thirty four methods, eleven presets, four species, nineteen validation gates. Measured: zero dropouts through a five second morph across a species switch, a switch ready in 50 to 120 ms, 48 control extreme loads without a throw. A local lab page for tuning by ear found a Flowers range error on its first A/B and measured that half the controls are inaudible on one held note, which is the input to the next release, a sound pass. The live control surface runs at sound-engine.xyz.
Stack
TypeScript, Web Audio, Tone.js, Web MIDI, Vite
Surface
Public tier (plantasia-sound-engine/public): engine, presets, adapter, events, analysis. Root export adds the v1 preset API and internals
Platform
Any browser with Web Audio; audio unlocks on a user gesture








Give Plantasonic a sound layer that behaves like a living thing, that any instrument app can mount in a few lines, and that tells the visual layer what it is doing.
Plantasonic instruments needed generative, botanical sound with a consistent feel across apps. A preset library could not carry that: presets recall moments, and each app would end up re-implementing how sound evolves, ages, and answers performance. The engine had to own that behavior once.
Two users again. The app author needs a safe, small API that cannot be called in the wrong order and that reports what the sound is doing. The player needs a handful of controls that feel like forces, not parameters: turn up growth and the world gets busier, turn up mold and it decays, whichever species is playing.
The v1 engine was preset centric. v2 reorganized everything around species: a plugin with its own synthesis graph that interprets the five shared ecological controls its own way. The preset system stayed, but every preset now resolves to a species plus an ecology. The tradeoff: two audio paths coexist during the transition (a Tone.js chain for v1 and per species graphs for v2), and the demo's analyser only listens to one of them, which is the first fix on the engine's list.
The architecture landed under a premature v2.0.0 tag before the host contract was real. Rather than build on it, I deprecated the tag, listed the integration blockers (lifecycle contract, playable only registry, unified facade, event bus, scheduler, MIDI, migration guide, browser sonic test, CPU budget test, adapter and integration doc), shipped all of them as 1.0.0 beta 1, and told hosts to pin that. The demo went through a validation pass that removed every control not wired to a real engine call. 1.0.0 followed once the surface was measured, not just built.
Before calling the public API stable I wrote a Playwright harness that plays the built engine in Chromium and WebKit and measures what a player feels: the time from noteOn to the first audible sample, located to the sample on a tap of the master bus, and dropouts over a minute of generative playback while a fake visual loop burns eight milliseconds of every frame. The first run measured 102 ms of latency: Tone.js schedules a tenth of a second ahead by default. Setting the lookahead to ten milliseconds brought it to 12 ms with zero dropouts in both browsers. The harness also showed that on a single held note the five ecological controls move the spectrum less than the voice moves itself; they act on the population, which is the design, and now it is written down rather than assumed. In 1.2 the harness moved into CI and grew rows for control extremes, a morph across a species switch, and per control audibility; a lab page built for tuning by ear found, on its first A/B, that Flowers threw a range error above ninety percent bloom, a bug no gate had reached because no gate had pushed a control to its edge.
Layers
Validation gates on every build
Browser performance harness
Shared controls with species specific mappings is the idea that made the engine feel like one instrument instead of four. The honest beta was the right call; the premature major tag cost more trust than the extra week would have. The master analyser that every path feeds should have come first; when it landed, the stage lit up for the whole engine, and the harness built on it found that the default scheduling lookahead put a hundred milliseconds between noteOn and sound. Ten lines fixed it; the point is that it was measured before the surface was called stable. Eight placeholder species were cut rather than kept as promises. Modulation followed in 1.1, designed the same way: a grill first, a decisions table, then the code, then the harness rows before the tag. 1.2 held to it and added a rule: build the measuring tool before the work it measures. The lab page came first so the sound pass could start whenever ears were free, and it paid for itself the day it was built. The grill after that asked what the engine is in one sentence, and the answer, an instrument that plays itself and answers you, reordered the docs and the demo without touching a line of engine code: simpler is what you read first, not what exists.