Granular synthesis breaks audio into tiny grains—milliseconds long—and reassembles them for wildly creative textures. In this article, we’ll implement real-time granular playback using JavaScript and the Web Audio API. No frameworks. Just buffers, randomness, and some timing magic.

Why Granular Synthesis?


Use cases include:


  • Stretching audio without pitch change
  • Soundscapes, ambient layers, and glitch art
  • Creative remixes and live audio manipulation

Step 1: Load and Decode the Audio File


Start by fetching and decoding audio into an AudioBuffer:


const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

async function loadSample(url) {
const res = await fetch(url);
const arrayBuffer = await res.arrayBuffer();
return await audioCtx.decodeAudioData(arrayBuffer);
}

Step 2: Create a Granular Playback Function


We’ll randomly select small grains and play them as overlapping buffer sources:


function playGrain(buffer, grainSize = 0.1, overlap = 0.05) {
const duration = buffer.duration;
const now = audioCtx.currentTime;

const interval = grainSize - overlap;

const grainInterval = setInterval(() => {
const startTime = Math.random() * (duration - grainSize);
const grainSource = audioCtx.createBufferSource();
grainSource.buffer = buffer;

const grain = audioCtx.createBuffer(1, audioCtx.sampleRate * grainSize, audioCtx.sampleRate);
grain.copyToChannel(buffer.getChannelData(0).slice(
  startTime * audioCtx.sampleRate,
  (startTime + grainSize) * audioCtx.sampleRate
), 0);

grainSource.buffer = grain;
grainSource.connect(audioCtx.destination);
grainSource.start();

}, interval * 1000);

// Stop after 10 seconds
setTimeout(() => clearInterval(grainInterval), 10000);
}

Step 3: Load, Then Trigger Playback


Now load a sample and start the granular engine:


loadSample('your-audio-file.mp3').then(buffer => {
playGrain(buffer, 0.1, 0.03); // grain size = 100ms, 30ms overlap
});

Pros and Cons

✅ Pros


  • Creative and flexible audio manipulation
  • Minimal setup using native Web APIs
  • Good performance on modern browsers

⚠️ Cons


  • Manual slicing can get computationally expensive
  • Requires fine-tuning for musicality
  • No out-of-the-box UI — you build it all

🚀 Alternatives


  • Tone.js GrainPlayer: Higher-level granular API
  • WebAssembly: For more performant DSP in complex grains
  • Pure Data / WebPd: More abstract, patch-based granular control

Summary


Granular synthesis in the browser is surprisingly doable with Web Audio API. This technique opens up expressive possibilities for generative music, sound installations, or experimental UIs. From glitchy textures to subtle ambiances, it’s a sound designer’s playground—entirely client-side.

If this was useful, you can support me here: buymeacoffee.com/hexshift