block by alexmacy d0b37a188f9a92890c43d6944bff0847

Rotating Ellipses v2

Full Screen

This listens to your computer’s microphone and draws the contents of the audio buffer as a series of ellipses that are rotated based upon the audio sample’s position in the buffer. The difference between this one and v1 is that v1 has a sort of threshold so that it only shows values above a certain level. To compensate, the line on v2 is 1/10 the width.

This was made as part of a series exploring the visualization of audio that was presented at a d3.oakland. A big list of the demos from this series can be found here.

index.html

<!DOCTYPE html>
<title>Rotating Ellipses v2</title>
<body style="margin: 0px">
  <canvas></canvas>
</body>
<script>
const width = innerWidth;
const height = innerHeight;

const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const analyser = audioCtx.createAnalyser();

const canvas = document.querySelector('canvas');
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);

const canvasCtx = canvas.getContext("2d");
canvasCtx.fillStyle = 'rgb(0, 0, 0)';
canvasCtx.strokeStyle = 'rgb(255, 0, 0)';
canvasCtx.lineWidth = .1;

const dataArray = new Uint8Array(analyser.frequencyBinCount);

navigator.getUserMedia (
  {audio: true},
  function(stream) {
    audioCtx.createMediaStreamSource(stream).connect(analyser);
    draw();
  },
  function(err) {
    console.log('The following gUM error occured: ' + err);
  }
);

function draw() {
  canvasCtx.fillRect(0, 0, width, height);
  analyser.getByteTimeDomainData(dataArray);
  const [min, max] = [Math.min(...dataArray), Math.max(...dataArray)];
  if (max - min > 1) {
    for(let i = 0; i < dataArray.length; i++) {
      if (dataArray[i] === 127) continue;
      const thisVol = ((dataArray[i] - min)/(max-min)) * Math.min(width, height)/2;
      const thisRotation = i/dataArray.length * Math.PI
      
      canvasCtx.beginPath();
      
      canvasCtx.ellipse(
        width/2, 
        height/2, 
        thisVol/2 + 1, 
        thisVol + 1, 
        thisRotation, 
        0, 
        2 * Math.PI
      );
      canvasCtx.stroke();
    }
  }
  requestAnimationFrame(draw);
};
</script>