Audio & Music Toys
RETRO SYNTH SOUNDBOARD
100% browser-synthesized drum pad & soundboard. Click pads or press hotkeys (1-9) to play synthesized kicks, snares, lasers, coins, and chimes.
1
808 KICK
2
SNARE
3
HI-HAT
4
COIN
5
LASER
6
JUMP
7
POWER-UP
8
SYNTH CHIME
9
SUB BASS
Developer Reference
Core Algorithm & Standalone Script
Standalone, zero-dependency JavaScript implementation powering this tool. Free to inspect, copy, and build upon.
let audioCtx = null;
function initAudio() {
if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
if (audioCtx.state === 'suspended') audioCtx.resume();
}
function triggerSound(type) {
initAudio();
const now = audioCtx.currentTime;
if (type === 'kick') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.frequency.setValueAtTime(150, now);
osc.frequency.exponentialRampToValueAtTime(0.01, now + 0.3);
gain.gain.setValueAtTime(1, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.3);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.3);
} else if (type === 'snare') {
const bufferSize = audioCtx.sampleRate * 0.2;
const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < bufferSize; i++) data[i] = Math.random() * 2 - 1;
const noise = audioCtx.createBufferSource();
noise.buffer = buffer;
const gain = audioCtx.createGain();
gain.gain.setValueAtTime(0.8, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.2);
noise.connect(gain); gain.connect(audioCtx.destination);
noise.start(now);
} else if (type === 'hihat') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'highpass';
osc.frequency.setValueAtTime(8000, now);
gain.gain.setValueAtTime(0.3, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.08);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.08);
} else if (type === 'coin') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'square';
osc.frequency.setValueAtTime(987, now);
osc.frequency.setValueAtTime(1318, now + 0.08);
gain.gain.setValueAtTime(0.5, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.25);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.25);
} else if (type === 'laser') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(1200, now);
osc.frequency.exponentialRampToValueAtTime(100, now + 0.15);
gain.gain.setValueAtTime(0.5, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.15);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.15);
} else if (type === 'jump') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'square';
osc.frequency.setValueAtTime(150, now);
osc.frequency.exponentialRampToValueAtTime(600, now + 0.2);
gain.gain.setValueAtTime(0.5, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.2);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.2);
} else if (type === 'powerup') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'triangle';
osc.frequency.setValueAtTime(300, now);
osc.frequency.exponentialRampToValueAtTime(1200, now + 0.4);
gain.gain.setValueAtTime(0.6, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.4);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.4);
} else if (type === 'chime') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'sine';
osc.frequency.setValueAtTime(1760, now);
gain.gain.setValueAtTime(0.6, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.8);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.8);
} else if (type === 'bass') {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'triangle';
osc.frequency.setValueAtTime(80, now);
osc.frequency.exponentialRampToValueAtTime(40, now + 0.5);
gain.gain.setValueAtTime(0.8, now);
gain.gain.exponentialRampToValueAtTime(0.01, now + 0.5);
osc.connect(gain); gain.connect(audioCtx.destination);
osc.start(now); osc.stop(now + 0.5);
}
}
document.querySelectorAll('.pad-btn').forEach(btn => {
btn.addEventListener('click', () => {
const sound = btn.dataset.sound;
btn.classList.add('active');
setTimeout(() => btn.classList.remove('active'), 120);
triggerSound(sound);
});
});
window.addEventListener('keydown', e => {
const btn = document.querySelector(`.pad-btn[data-key="${e.key}"]`);
if (btn) {
btn.click();
}
});