block by alexmacy 455d69e7617c0c7c60ba3b55fedb21e2

Rotating Ellipses v1

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.

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 v1</title>
<script src="//d3js.org/d3.v4.min.js"></script>
<body style="margin: 0px">
  <canvas></canvas>
</body>
<script>  
const width = innerWidth;
const height = innerHeight;

const volScale = d3.scaleLog().range([0, 300])

navigator.getUserMedia = (navigator.getUserMedia ||
                          navigator.webkitGetUserMedia ||
                          navigator.mozGetUserMedia ||
                          navigator.msGetUserMedia);

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.lineWidth = 1;
canvasCtx.strokeStyle = 'rgb(255, 0, 0)';
analyser.fftSize = 256;

const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);

if (navigator.getUserMedia) {
  navigator.getUserMedia (
    {audio: true},
    function(stream) {
      audioCtx.createMediaStreamSource(stream).connect(analyser);
      draw();
    },
    function(err) {
      console.log('The following gUM error occured: ' + err);
    }
  );
} else {
   console.log('getUserMedia not supported on your browser!');
}

function draw() {
  analyser.getByteTimeDomainData(dataArray);  
  const volExt = d3.extent(dataArray)
  volScale.domain(volExt[1] - volExt[0] < 2 ? [127, 127] : d3.extent(dataArray))
  
  canvasCtx.fillRect(0, 0, width, height);
  canvasCtx.beginPath();
  for(let i = 1; i < bufferLength; i++) {
    const thisVal = volScale(dataArray[i])
    const thisRotation = i/dataArray.length * Math.PI;
    canvasCtx.ellipse(width/2, height/2, thisVal/2, thisVal, thisRotation, 0, 2 * Math.PI);
  }
  canvasCtx.stroke();
  requestAnimationFrame(draw);
};
</script>