JSFiddle - React, Tailwind, and code Playground

by atesgoral

HTML

<canvas id="c1" width="512" height="255"></canvas><canvas id="c2" width="255" height="255"></canvas>

CSS

#c1 { background: white }
#c2 { background: blue }

JavaScript

const url = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/new_year_dubstep_minimix.ogg';

const context = new AudioContext();

const sourceNode = context.createBufferSource();

const processor = context.createScriptProcessor(2048, 1, 1);

const analyser = context.createAnalyser();
analyser.smoothingTimeConstant = 0.3;
analyser.fftSize = 1024;
        
sourceNode.connect(analyser);
analyser.connect(processor);

const bins = new Uint8Array(analyser.frequencyBinCount);
const ctx1 = c1.getContext('2d');
const ctx2 = c2.getContext('2d');

let beat = 0;

function render() {
	requestAnimationFrame(render);
  
  //ctx1.clearRect(0, 0, c1.width, c1.height);
  ctx1.fillStyle = '#ffffff';
  ctx1.globalAlpha = 0.333;
  ctx1.fillRect(0, 0, c1.width, c1.height);
  
  ctx1.globalAlpha = 1;
  ctx1.fillStyle = '#000000';
  
  for (let i = 0; i < bins.length; i++) {
  	ctx1.fillRect(i, 255 - bins[i], 1, bins[i]);
  	//ctx1.fillRect(i, 255 - bins[i], 1, 5);
  }
    
  ctx2.clearRect(0, 0, c2.width, c2.height);
  ctx2.fillStyle = '#ffffff';
  ctx2.beginPath();
  ctx2.arc(c2.width / 2, c2.height / 2, beat * c2.width / 2, 0, 2 * Math.PI);
  ctx2.fill();
}

render();

let prevAvg = 0;

processor.onaudioprocess = function () {
  analyser.getByteFrequencyData(bins);

	let sum = 0;
  
  for (let i = 0; i < bins.length; i++) {
  	sum += bins[i];
  }
  
  const avg = sum / bins.length;
  
  if (avg - prevAvg > 20) {
  	beat = 1;
  } else {
  	beat *= 0.5;
    //beat = 0;
  }
  
  prevAvg = avg;
  
  //beat = avg;
};

processor.connect(context.destination);

sourceNode.connect(context.destination);

const request = new XMLHttpRequest();

request.open('GET', url, true);
request.responseType = 'arraybuffer';

request.onload = function () {
  //console.log('Loaded');
  
  context.decodeAudioData(request.response, function (buffer) {
	  //console.log('Decoded');
    sourceNode.buffer = buffer;
    sourceNode.start(0);
  }, function (error) {
  	console.error(error);
  });
}

request.send();