About me ↗
← The notebook

Web Audio: Why Not Build Cool Audio Stuff Directly in the Browser?

A little drum machine, a step sequencer, a bass synth. Let's open a URL and make a beat, then see where this experiment takes us.

EXPERIMENT 002 / WEB AUDIO

BROWSER BEATS

SOUND ON YOUR TERMS
01 / 16
PATTERN

01 / CHANNEL RACK

CLICK TO PLACE A HIT
VOICE12345678910111213141516
Kick
Snare
Closed hat
Open hat
Clap
Bass
Select a step, then adjust its strength.

02 / BASS PIANO ROLL

D MINOR · ONE NOTE PER STEP
D3
C3
B♭2
A2
G2
F2
D2
C2

03 / MIXER

MAKE SOME ROOM
Kick
Snare
Closed hat
Open hat
Clap
Bass
Loading your workspace…

Press Play, change a few steps, follow the groove. B–D are blank canvases. Audio pauses when you leave this tab.

Browsers can do a ridiculous amount of stuff now. So why not build some cool audio stuff directly in one?

That's the question behind this experiment. I want to open a URL and, a few seconds later, start making a beat. A little drum machine. Some patterns. A bass line. Enough controls to get somewhere unexpected.

The instrument above is the first version. Press Play. Move a kick. Turn down the hats. Click a few notes into the bass piano roll. The starter groove is there so you can hear what your changes do immediately.

You can also open Browser Beats on its own page.

Start with the fun part

The inspiration is the Channel Rack in FL Studio: choose a sound, put hits on a grid, listen, change something. That short distance between an idea and hearing it is what I want to explore.

This version has sixteen steps and six voices: kick, snare, closed hat, open hat, clap, and bass. The drum sounds are synthesized from oscillators and noise; there isn't a sample pack to download. The bass is a filtered sawtooth oscillator with a short envelope.

Each row loops over one bar. Put a snare on steps 5 and 13 for a backbeat, then move the kick around it. Select a step and use the velocity slider to change its strength. Try quieter hits between the main ones.

Swing stretches the first sixteenth note of each pair and shortens the second. The bar stays the same length, but the groove leans differently. Start with a little and turn it up until it feels good.

The piano roll offers a small selection of notes from D minor. Click to place a bass note; click it again to remove it. One note per step is enough for this first experiment.

Four patterns, a tiny mixer

Pattern A starts with a beat. B, C, and D are empty. Copy A into B, switch to B, and make a variation. Pattern changes take effect at the next scheduling opportunity, so they're immediate edits rather than queued song transitions.

Each voice has level, pan, mute, and solo controls. Multiple voices can be soloed together. Mute still wins if both buttons are on. The master output has some headroom and a compressor to help contain peaks.

Edits save in this browser's local storage. Both the article and the standalone instrument use the same storage key, so reopening either restores your latest saved workspace. They're not synchronized live across tabs. Export JSON to keep a portable copy, and import it to continue later. Undo keeps the last thirty edits during your visit.

There are no accounts or cloud projects here yet. Clearing browser data clears the saved workspace too.

Timing is the interesting bit

A JavaScript timer wakes up our scheduler every 25 milliseconds. It looks 100 milliseconds ahead and schedules sounds against the audio clock. The timer keeps the queue supplied; Web Audio handles the scheduled start times.

This follows the approach in MDN's guide to sequencing audio. AudioContext.currentTime gives those scheduled events a shared timeline.

The visual playhead follows the queued events. It can lag slightly because it updates on the UI thread. Heavy main-thread work can also exhaust the scheduling buffer. This is a small foreground instrument; it pauses when you leave the tab.

The implementation uses native Web Audio nodes. More demanding processing could be a reason to explore AudioWorklets or WebAssembly later. First I want this interaction to feel good.

The beat is data

The interface and audio engine read the same project state. A hit is a velocity value. A bass note is a pitch. Patterns are arrays, and mixer settings are numbers and booleans.

A simplified slice looks like this:

{
  "bpm": 96,
  "swing": 0.12,
  "kick": [0.85, 0, 0, 0, 0, 0, 0.85, 0, 0.85, 0, 0.85, 0, 0, 0, 0, 0],
  "snare": [0, 0, 0, 0, 0.85, 0, 0, 0, 0, 0, 0, 0, 0.85, 0, 0, 0]
}

That makes saving and copying patterns straightforward. It also gives future tools something concrete to edit.

Then we can make it weird

Eventually, I'd like to type: “Make the hats less robotic.” An agent could change velocities and placement in the same grid I'm using. “Keep the drums, try a different bass line.” It could edit only the notes.

Every change would stay visible and editable. That's the AI direction I'm curious about: working inside the instrument together, with a composition we can inspect and change.

There is no AI connected to this prototype yet. Semantic undo, sharing by URL, version history, and collaboration are ideas for later. Right now we have a local beat machine and ordinary undo.

What I want to learn

Can this feel immediate enough that I stop thinking about the browser? Can a tiny set of sounds and controls keep me playing? What do I reach for first when the limitations show up?

Sample loading, a longer piano roll, and a playlist for arranging patterns would be useful next experiments. Effects and automation could follow. The test is whether each addition makes it more fun to use.

For now: hit Play. Make a beat. See what happens.

← Back to the notebook