<div id="screen">
  <svg></svg>
</div>
<button id="play-audio">Play Audio</button>
<audio crossOrigin="anonymous" src="http://rumyrashead.com/media/screwUp.mp3" id="music-track"></audio>
<p class="credit">Music: <a href="https://soundcloud.com/kinnoha/screw-up-prod-by-krikit-boi">Screw Up by Kinnoha</a></p>
body {
  padding:0px; margin:0px;
  position:relative;
  font-family: sans-serif;
}

#screen, svg {width:100vw; height:100vh; padding:0px; margin:0px;}

#screen {background: #fefef5;}

#play-audio {
  position:absolute; top:0px; left:50%;
  width:20%; margin:1em 0px 1em -10%;
  padding:0.5em;
  background:hsla(240,65%,65%,0.7); box-shadow:0.5px 0.5px 4px #333;
  border:1px solid white; border-radius:1em;
  color:white; font-size:1.1em;
  letter-spacing:0.5px;
  &:hover {
    cursor:pointer;
    background:hsla(240,65%,55%,0.7); box-shadow:0px 0px 2px #333;
  }
}
.credit {
  position:absolute; bottom:10px; right:10px;
  a {font-size:100%; color:hsla(240,65%,55%,0.7); &:hover{text-decoration:none;}}
}
View Compiled
// set up audio context
var audioContext = (window.AudioContext || window.webkitAudioContext);

var audioApi = new audioContext;

const audioEl = document.getElementById('music-track'),
  playButton = document.getElementById('play-audio'),
  audioTrack = audioApi.createMediaElementSource(audioEl);

// variables
var analyserNode = audioApi.createAnalyser(),
    frequencyData = new Uint8Array(2048);

analyserNode.fftSize = 4096;

function connectTrack() {
  console.log('fired');
  audioTrack.connect(analyserNode);
  audioTrack.connect(audioApi.destination);
  analyserNode.connect(audioApi.destination);
  audioEl.play();
  drawSunburst();
}

playButton.onclick = function() {
  if (audioEl.paused) {
    connectTrack();
    console.log('play');
  } else {
    audioEl.pause();
    console.log('pause');
  }
}

function adjustFreqData() {
  analyserNode.getByteFrequencyData(frequencyData);
  frequencyData.slice(0,512);
  
  var newFreqs = [], prevRangeStart = 0, prevItemCount = 0;
  // looping for my new 16 items
  for (let j=1; j<17; j++) {
    var pow, itemCount, rangeStart;
    if (j%2 === 1) {
      pow = (j-1)/2;
    } else {
      pow = j/2;
    }
    itemCount = Math.pow(2, pow);
    if (prevItemCount === 1) {
      rangeStart = 0;
    } else {
      rangeStart = prevRangeStart + (prevItemCount/2);
    }

    var newValue = 0, total = 0;
    for (let k=rangeStart; k<rangeStart+itemCount; k++) {
      // add up items and divide by total
      total += frequencyData[k];
      newValue = total/itemCount;
    }
    newFreqs.push(newValue);

    prevItemCount = itemCount;
    prevRangeStart = rangeStart;
  }
  return newFreqs;
}

// enter and exit
var width = window.innerWidth,
    height = window.innerHeight,
    radius = Math.min(width, height) / 2;

var svg = d3.select("svg")
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height * .52 + ")");
var g = d3.select("g");
var arcs = g.selectAll("path");

var arc = d3.svg.arc()
    .startAngle(function(d, i) { return (i/8)*Math.PI; })
    .endAngle(function(d, i) { return ((i+1)/8)*Math.PI; })
    .innerRadius(function(d, i) { return radius/3; })
    .outerRadius(function(d, i) { return d*1.6; });

function drawSunburst() {

  requestAnimationFrame(drawSunburst);
  // var newData = adjustFreqData();
  arcs = arcs.data(adjustFreqData());

  arcs
    .enter().append("path")
    .style("stroke", "#fff");

  arcs
    .attr("d", arc)
    .style("fill", function(d,i) { return 'hsla('+(360-(i*10))+',65%,'+Math.floor(d/2.5)+'%,'+d/350+')'; })
    .exit().remove();
}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js