This is where the magic happens…

  createVisualizer() {

    this.audioContext = new AudioContext();

    if (!this.audioElem) {
      return;
    }

    this.audioElem.crossOrigin = "anonymous"; // Otherwise the browser moans

    const src = this.audioContext.createMediaElementSource(this.audioElem);
    const analyser = this.audioContext.createAnalyser();

    src.connect(analyser);
    analyser.connect(this.audioContext.destination);
    analyser.fftSize = 128; // Bump to 256 to get small sample rate

    const vis = document.getElementById("vis");
   
    // Still dont understand this bit
    const bufferLength = analyser.frequencyBinCount;
    const dataArray = new Uint8Array(bufferLength);

    let barHeight: any;

    function renderFrame() {
      requestAnimationFrame(renderFrame);

      analyser.getByteFrequencyData(dataArray);

      for (let i = 0; i < bufferLength; i++) {
        barHeight = dataArray[i]; // This is our magic number that will fluctuate up and down for our data viz!

        if (barHeight < 50) {
          return;
        }

        vis!.style.height = `${barHeight + 100}px`;
        vis!.style.width = `${barHeight + 100}px`;
    
      }
    }
    renderFrame();
  }