JSFiddle - React, Tailwind, and code Playground

by greweb

HTML

Press <strong>Run</strong> to try a new random FM sound!

JavaScript

// by @greweb
// Experimenting with Frequency Modulation + Filter Cutoff

var NOTES = (function () {
  var notes = {};
  var toneSymbols = "CcDdEFfGgAaB";
  function noteToFrequency (note) {
    return Math.pow(2, (note-69)/12)*440;
  };
  for (var octave = 0; octave < 8; ++octave) {
    for (var t = 0; t < 12; ++t) {
      notes[toneSymbols[t]+octave] = noteToFrequency(octave * 12 + t);
    }
  }
  return notes;
}());

var context = new webkitAudioContext();

function Modulator (type, freq, gain) {
  this.osc = context.createOscillator();
  this.out = this.gain = context.createGainNode();
  this.osc.type = type;
  this.osc.frequency.value = freq;
  this.gain.gain.value = gain;
  this.osc.connect(this.gain);
  this.osc.start(0);
}

var compressor = context.createDynamicsCompressor();

var gain = context.createGainNode();
gain.gain.value = 1;


// Make an oscillator, connect the modulator stack, play it!
var osc = context.createOscillator();
osc.type = "triangle";
var note = NOTES.G4;
var speed = 2;

osc.frequency.setValueAtTime(note, 0);

var lfo2 = new Modulator("square", 2.03 * note, note / 3);
var lfo2bis = new Modulator("sawtooth", 0.501 * note, note);
var lfo = new Modulator("sine", 0.251 * note, note);

lfo2.osc.detune.value = -7;
lfo2bis.osc.detune.value = -10;
lfo.osc.detune.value = 3;

lfo2.out.connect(lfo2bis.gain.gain);
lfo2bis.out.connect(lfo.gain.gain);
lfo.out.connect(osc.frequency);

var filter = context.createBiquadFilter();
filter.Q.value = 2;
filter.frequency.value = 500;

var filterLFO = new Modulator("sine", speed, 500);
filterLFO.out.connect(filter.frequency);

var bp = context.createBiquadFilter();
bp.type = "highpass";
bp.Q.value = 0;
bp.frequency.value = 5000;

var bpMod = new Modulator("sawtooth", speed/2, 5000);
bpMod.out.connect(bp.frequency);

osc.connect(gain);
gain.connect(bp);
gain.connect(filter);

var gainLFO = new Modulator("sine", speed/4,...