Soundscape: Reactive Audio for the Web
The Idea
I've been thinking about ambient sound on the web. Not a Spotify embed or a looping MP3 — something that's alive. Something that generates music in real-time, reacts to what you're looking at, and never plays the same thing twice.
So I built the first version of Soundscape — a generative audio engine running entirely in the browser using Tone.js. No samples, no pre-recorded loops. Every note, every chord, every drum hit is synthesised on the fly.
How It Works
The engine has four layers that run simultaneously:
- Pad — FM-synthesised chords cycling through jazz voicings (lo-fi) or power chords (punk/grunge)
- Bass — Sub-bass following the chord roots, routed around the master filter so the low end stays full
- Melody — Motif-based phrase generation with chord-tone targeting and velocity contouring
- Drums — Style-specific patterns: swung lo-fi grooves, driving punk 16ths, or heavy grunge double-kicks
- Texture — Brown noise filtered into vinyl crackle
Everything runs through an effects chain — low-pass filter, bitcrusher, reverb, feedback delay — and every parameter responds to the current mood.
Reactive Browsing
Each page on the site has a mood profile. Navigate to the journal and the tempo drops, the filter closes, reverb deepens — reading mode. Hit the store and it opens up, picks up energy. The soundscape page gives you full manual control.
The mood system uses four parameters — energy, brightness, density, and warmth — that map to real synth parameters:
| Parameter | Controls | |---|---| | Energy | Tempo, drum velocity, melodic intensity | | Brightness | Filter cutoff, reverb decay | | Density | Note probability, layer activity | | Warmth | Bitcrusher depth, delay feedback |
Transitions between moods are smoothed over 2.5 seconds with eased interpolation. No jarring jumps.
Three Styles
The engine doesn't just do lo-fi. There are three distinct musical styles, each with their own chord progressions, scales, drum patterns, and synth tones:
Lo-fi — Jazzy 7th chords, pentatonic melodies, swung drums, warm FM synthesis. The classic study-beats vibe.
Punk — Power chords in E, 150-195 BPM, relentless 16th-note hi-hats, sawtooth buzz, no swing. Fast ascending runs and hammered repeated notes.
Grunge — Heavy power chords with chromatic descent, blues scale, double-kick hits, square wave fuzz. Slow, sludgy, cavernous.
The Melody Problem
The first version sounded like a cat walking on a keyboard. Random walks on a pentatonic scale with dice-roll probability per beat — technically "generative", practically unlistenable.
The fix was to think about how melody actually works. Humans don't perceive random notes — they perceive patterns. So the engine now generates structured phrases:
- Pick a motif — a short melodic shape defined as scale-degree intervals
- Pick a rhythm cell — which beats in the bar actually get notes
- Play the motif, then rest, then play a variation (inverted or transposed)
- Resolve — step toward a chord tone and land on it
- Breathe — occasional rest bars between phrases
Each style has its own motif library. Lo-fi gets gentle stepwise motion and neighbor tones. Punk gets charging runs and aggressive stabs. Grunge gets slow bends and dramatic plunges.
The velocity follows a contour across the phrase — builds to a peak, then resolves softer. Combined with chord-tone targeting on strong beats, it sounds like someone is actually playing.
What's Next
This is a proof of concept. The interactive page is live at /soundscape — you can switch styles, adjust mood parameters, toggle layers, and watch the FFT visualiser react.
Things I want to explore:
- Scroll reactivity — modulate filter cutoff and density based on scroll velocity
- Time-of-day awareness — night mode auto-engages after dark
- More styles — ambient, synthwave, metal
- Motif memory — the engine remembers motifs it's played and brings them back later, building thematic coherence across a session
- Per-post mood tags — blog posts could declare their own mood in frontmatter
The toggle is in the bottom-right corner of every page. It's off by default — click play and see what happens.
Try It
Head to /soundscape and hit START. Switch between lo-fi, punk, and grunge. Crank the energy slider. Kill the drums and just listen to the pad and melody. Then navigate to a different page and hear the mood shift.
Every session is unique. Nothing is pre-recorded. It's all just maths and oscillators.