🔍

LET’S BUILD AND 8-BIT SOUND GENERATOR

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


ONLINE EDITOR VERSION

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;
  
  
}