Wiggle Synth

Add some sparkly happy emoji particles for nauseating cheese

by soulwire

HTML

Wiggle

Babel + JSX

const NOTES = {
  'C'  : 60,
  'C#' : 61,
  'D'  : 62,
  'D#' : 63,
  'E'  : 64,
  'F'  : 65,
  'F#' : 66,
  'G'  : 67,
  'G#' : 68,
  'A'  : 69,
  'A#' : 70,
  'B'  : 71
};
const PENTATONIC = ['C6', 'A5', 'G5', 'E5', 'D5', 'C5', 'A4', 'G4', 'E4', 'D4', 'C4', 'A3'];
const BASE_KEY = NOTES['A'];
const BASE_OCTAVE = 4;

const audio = new AudioContext();
const master = audio.createGain();
master.gain.value = 0.5;

const delay = audio.createDelay();
delay.delayTime.value = 0.2;
delay.connect(master);

const compressor = audio.createDynamicsCompressor();
compressor.threshold.value = -50;
compressor.knee.value = 40;
compressor.ratio.value = 12;
//compressor.reduction = -20;
compressor.attack.value = 0;
compressor.release.value = 0.25;

master.connect(delay);
master.connect(compressor);
compressor.connect(audio.destination);

const noteToFrequency = (note = 'C6', baseOctave = BASE_OCTAVE) => {
	const octave = parseInt(note.match(/\d+/)[0], 10);
  const key = note.match(/[A-G\#]+/i)[0];
  const o = octave - baseOctave;
  const k = NOTES[key] - BASE_KEY;
  const n = k + (12 * o);
  return 440 * Math.pow(2, n / 12);
}

const playNote = (note, octave = BASE_OCTAVE, attack = 0, release = 20, sustain = 1, decay = 20) => {
	const oscillator = audio.createOscillator();
  const envelope = audio.createGain();
  const frequency = noteToFrequency(note, octave);
  //console.log(note, frequency);
  oscillator.type = 'sine';
  oscillator.frequency.value = frequency;
  oscillator.connect(envelope);
  envelope.connect(compressor);
  
  let now = audio.currentTime;
  let end = now + (attack / 10);
  
  envelope.gain.setValueAtTime(0, now);
  envelope.gain.linearRampToValueAtTime(1, end);
  envelope.gain.setTargetAtTime(sustain / 100, end, decay / 100 + 0.001);
	
  oscillator.frequency.setValueAtTime(frequency, 0);
  oscillator.start(0);
  
  end = now + release / 10;
  
  envelope.gain.cancelScheduledValues(now);
  envelope.gain.setValueAtTime(envelope.gain.value, now);
 ...