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,...