This tool lets you create classic video game sounds by tweaking parameters like wave type, frequency, and envelope. It’s designed with simplicity in mind, allowing you to craft unique sound effects without needing deep technical knowledge. The core of this tool is built on JavaScript p5.js and Web Audio API, ensuring smooth, real-time sound synthesis directly in your browser. Whether you’re a game developer or just a retro sound enthusiast, dive in and start experimenting!
basic generator + sound visualization
let alive = 0; let xoff = 0; let yoff = 0; let wave = []; let waveGraphics; let waveWidth = 800 - 2 * 40; let playbackPosition = 0; let soundDuration = 0; let soundStartTime = 0; let pad = 40; let sound = { "oldParams": true, "wave_type": 1, "p_env_attack": 0, "p_env_sustain": 0.31718502829007483, "p_env_punch": 0, "p_env_decay": 0.2718540993592685, "p_base_freq": 0.26126191208337196, "p_freq_limit": 0, "p_freq_ramp": 0.43787689856926615, "p_freq_dramp": 0, "p_vib_strength": 0, "p_vib_speed": 0, "p_arp_mod": 0, "p_arp_speed": 0, "p_duty": 1, "p_duty_ramp": 0, "p_repeat_speed": 0.7558565452384385, "p_pha_offset": 0, "p_pha_ramp": 0, "p_lpf_freq": 1, "p_lpf_ramp": 0, "p_lpf_resonance": 0, "p_hpf_freq": 0, "p_hpf_ramp": 0, "sound_vol": 0.25, "sample_rate": 44100, "sample_size": 8 }; function setup() { createCanvas(800, 600); waveGraphics = createGraphics(width, height); } function draw() { background(255); if (alive > 0.1) { alive *= 0.96; xoff = sin(millis() * 0.1) * alive * 30; yoff = sin(millis() * 0.3) * alive * 30; } let px = width / 2 + xoff; let py = height / 2 + yoff; fill(0); noStroke(); // Draw the pre-rendered waveform image(waveGraphics, 0, 0); } function mousePressed() { alive = 1; sound['wave_type'] = int(random() * 2) + 1; sound['p_base_freq'] = random() * 0.4 + 0.2; sound['p_freq_ramp'] = random() * 0.8 + 0.1; sound['p_vib_strength'] = random() * 0.7; sound['p_vib_speed'] = random() * 1.1; sound['p_repeat_speed'] = random() * 0.9 + 0.1; sound['p_env_attack'] = random() * 0.3 + 0.03; sound['p_env_sustain'] = random() * 0.03 + 0.01; sound['p_env_decay'] = random() * 0.1 + 0.3; sound['p_env_punch'] = random() * 0.8 + 0.1; sound['p_arp_speed'] = random() * 0.4 + 1.1; sound['p_arp_mod'] = random() * 0.4 + 0.5; var s = new SoundEffect(sound).generate(); wave = s.data; // Get waveform data soundDuration = s.getAudio().duration * 1000; soundStartTime = millis(); s.getAudio().play(); // Render the waveform to the PGraphics object waveGraphics.background(255); waveGraphics.fill(0); waveGraphics.beginShape(); for (let i = 0; i < wave.length; i++) { let x = map(i, 0, wave.length, pad, width - pad * 2); waveGraphics.point(x, wave[i]*2 + pad); } waveGraphics.endShape(); }
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script> <link rel="stylesheet" type="text/css" href="style.css"> <meta charset="utf-8" /> </head> <body> <script src="https://sfxr.me/riffwave.js"></script> <script src="https://sfxr.me/sfxr.js"></script> <script src="sketch.js"></script> </body> </html>
advanced generator + sound visualization
https://editor.p5js.org/brucexxxbanner/sketches/NrfXBIXQe
let alive = 0; let xoff = 0; let yoff = 0; let wave = []; let waveGraphics; let waveWidth = 800 - 2 * 40; let playbackPosition = 0; let soundDuration = 0; let soundStartTime = 0; let pad = 40; let sound = { "oldParams": true, "wave_type": 1, "p_env_attack": 0.03, "p_env_sustain": 0.317, "p_env_punch": 0, "p_env_decay": 0.272, "p_base_freq": 0.261, "p_freq_limit": 0, "p_freq_ramp": 0.438, "p_freq_dramp": 0, "p_vib_strength": 0, "p_vib_speed": 0, "p_arp_mod": 0, "p_arp_speed": 0, "p_duty": 1, "p_duty_ramp": 0, "p_repeat_speed": 0.756, "p_pha_offset": 0, "p_pha_ramp": 0, "p_lpf_freq": 1, "p_lpf_ramp": 0, "p_lpf_resonance": 0, "p_hpf_freq": 0, "p_hpf_ramp": 0, "sound_vol": 0.25, "sample_rate": 44100, "sample_size": 8 }; function setup() { createCanvas(800, 300); waveGraphics = createGraphics(width, height); // Set up slider controls select('#attack').input(() => sound.p_env_attack = float(select('#attack').value())); select('#sustain').input(() => sound.p_env_sustain = float(select('#sustain').value())); select('#decay').input(() => sound.p_env_decay = float(select('#decay').value())); select('#freq_ramp').input(() => sound.p_freq_ramp = float(select('#freq_ramp').value())); select('#vib_strength').input(() => sound.p_vib_strength = float(select('#vib_strength').value())); select('#vib_speed').input(() => sound.p_vib_speed = float(select('#vib_speed').value())); select('#repeat_speed').input(() => sound.p_repeat_speed = float(select('#repeat_speed').value())); select('#env_punch').input(() => sound.p_env_punch = float(select('#env_punch').value())); select('#arp_speed').input(() => sound.p_arp_speed = float(select('#arp_speed').value())); select('#arp_mod').input(() => sound.p_arp_mod = float(select('#arp_mod').value())); select('#randomize').mousePressed(randomizeParams); } function draw() { background(255); if (alive > 0.1) { alive *= 0.96; xoff = sin(millis() * 0.1) * alive * 30; yoff = sin(millis() * 0.3) * alive * 30; } let px = width / 2 + xoff; let py = height / 2 + yoff; fill(0); noStroke(); // Draw the pre-rendered waveform image(waveGraphics, 0, 0); } function mouseReleased() { generateAndPlaySound(); } function generateAndPlaySound() { let s = new SoundEffect(sound).generate(); wave = s.data; // Get waveform data soundDuration = s.getAudio().duration * 1000; soundStartTime = millis(); s.getAudio().play(); // Render the waveform to the PGraphics object waveGraphics.background(255); waveGraphics.fill(0); waveGraphics.beginShape(); for (let i = 0; i < wave.length; i++) { let x = map(i, 0, wave.length, pad, width - pad * 2); waveGraphics.point(x, wave[i] * 0.8 + pad, 4); } waveGraphics.endShape(); } function randomizeParams() { sound.p_env_attack = random() * 0.3 + 0.03; sound.p_env_sustain = random() * 0.3 + 0.01; sound.p_env_decay = random() * 0.1 + 0.3; sound.p_freq_ramp = random() * 0.8 + 0.1; sound.p_vib_strength = random() * 0.7; sound.p_vib_speed = random() * 1.1; sound.p_repeat_speed = random() * 0.9 + 0.1; sound.p_env_punch = random() * 0.8 + 0.1; sound.p_arp_speed = random() * 0.4 + 1.1; sound.p_arp_mod = random() * 0.4 + 0.5; select('#attack').value(sound.p_env_attack); select('#sustain').value(sound.p_env_sustain); select('#decay').value(sound.p_env_decay); select('#freq_ramp').value(sound.p_freq_ramp); select('#vib_strength').value(sound.p_vib_strength); select('#vib_speed').value(sound.p_vib_speed); select('#repeat_speed').value(sound.p_repeat_speed); select('#env_punch').value(sound.p_env_punch); select('#arp_speed').value(sound.p_arp_speed); select('#arp_mod').value(sound.p_arp_mod); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Sound Wave Visualizer</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script> <script src="https://sfxr.me/riffwave.js"></script> <script src="https://sfxr.me/sfxr.js"></script> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div id="controls"> <label for="attack">Attack:</label> <input type="range" id="attack" min="0" max="1" step="0.01" value="0.03"> <br> <label for="sustain">Sustain:</label> <input type="range" id="sustain" min="0" max="1" step="0.01" value="0.317"> <br> <label for="decay">Decay:</label> <input type="range" id="decay" min="0" max="1" step="0.01" value="0.272"> <br> <label for="freq_ramp">Frequency Ramp:</label> <input type="range" id="freq_ramp" min="0" max="1" step="0.01" value="0.438"> <br> <label for="vib_strength">Vibration Strength:</label> <input type="range" id="vib_strength" min="0" max="1" step="0.01" value="0"> <br> <label for="vib_speed">Vibration Speed:</label> <input type="range" id="vib_speed" min="0" max="1" step="0.01" value="0"> <br> <label for="repeat_speed">Repeat Speed:</label> <input type="range" id="repeat_speed" min="0" max="1" step="0.01" value="0.756"> <br> <label for="env_punch">Env Punch:</label> <input type="range" id="env_punch" min="0" max="1" step="0.01" value="0"> <br> <label for="arp_speed">Arpeggio Speed:</label> <input type="range" id="arp_speed" min="0" max="1" step="0.01" value="0"> <br> <label for="arp_mod">Arpeggio Mod:</label> <input type="range" id="arp_mod" min="0" max="1" step="0.01" value="0"> <br> <br> <button id="randomize">Randomize ALL</button> </div> <script src="sketch.js"></script> </body> </html>
html, body { margin: 0; padding: 0; background-color:#EEE; padding:20px; font-family: "Arial"; font-weight: bold; } canvas { display: block; } #controls{ font-size:0.8em; padding-bottom:40px; }