JSFiddle - React, Tailwind, and code Playground

by Santiago J

HTML

<h4>Frequency</h4>
<canvas id="fft-graph"></canvas>

CSS

body {
  background-color: #333;
  color: #eee;
  font-family: Verdana, sans-serif;
  font-size: 0.9em;
}
canvas {
  background-color: #111;
}

JavaScript

/// Silly unnecessary polyfilling
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;

/// Util functions
// query selector helper
function $(s,a,p) {
    if (typeof s !== "string") return s;
    p = p || document;
    return a ? p.querySelectorAll(s) : p.querySelector(s);
}
// sum the numbers in an array slice
function sumSlice(arr, a, b) {
    var sum = 0;
    for (var i = a; i < b; i++) {
        sum += arr[i];
    }
    return sum;
}
// graph a buffer on a given 2d canvas context
function graphBuffer(ctx, buff) {
    var n = buff.length,
        h = ctx.canvas.height;
    ctx.clearRect(0, 0, ctx.canvas.width, h);
    for (var i = 0; i < n; i++) {
        ctx.fillRect(i, h - buff[i] - 1, 1, 1);
    }
}


/// Set up us the canvas
var ctxfft = $("#fft-graph").getContext("2d"); // (not jQuery)
ctxfft.canvas.width = 1024; // half the fftSize
ctxfft.canvas.height = 256;
ctxfft.fillStyle = "#eeeeee";

/// Set up us the audio
(function() {
    if (typeof AudioContext !== "function") {
        throw new Error("AudioContext not supported!");
    }
    
    /* Graph:
        microphone -->- analyser (-->- modify gains[] params)

        oscillator -->- filters[] -->- gains[] -->- output
    */

    /// Graph nodes
    var
    mic,       // MediaStreamAudioSourceNode
    context    = new AudioContext,
    analyser   = context.createAnalyser(),
    gainNodes  = [],
    filters    = [],
    oscillator = context.createOscillator();


    /// Analyser (FFT) config
    analyser.fftSize = 2048; // fun fact: 2048 == 0x800
    analyser.smoothingTimeConstant = 0.65;
    var fftBuffer = new Uint8Array(analyser.frequencyBinCount);


    /// Vocoder config
    var numBands = 30;

    // freqBounds is an array of length (numBands + 1)
    // It defines the bounds for each band.
    // The bounds are spaced out logarithmically.
    var freqBounds = (function(freqStart, freqEnd,...