title: Pre-process audio data (fft spectrum, peak, etc.) in JavaScript
body: <p>I can currently play an audio track using the JavaScript Web Audio API. While this track is playing I can extract the FFT spectrum data, the peak value, the RMS value, etc.</p>
  
  <p>However, for the purposes of my application, I need to be able to extract all of this data from the track before I begin playing it.</p>
  
  <p>Is there any way to do this using the Web Audio API. If not, how else might this be done?</p>
  
  <p>I tried to achieve this by using the following code but it returned the exact same values for each 'frame':</p>
  
  <p>Loading the audio when the user chooses a file:</p>
  
  <pre><code>var fileChooser = document.getElementById("chooseAudio");
  var audio = null;
  
  var file = fileChooser.files[0];
  
  var reader = new FileReader();
  
  reader.onload = function(e) {
      audio = new Audio(reader.result);
  }
  
  reader.readAsDataURL(file);
  </code></pre>
  
  <p>Once the audio has been loaded:</p>
  
  <pre><code>var FPS = 60;
  var INCREMENT = 1 / FPS;
  var FFT_SIZE = 256;
  var SMOOTHING = 0.7;
  
  var duration = null;
  var length = null;
  var width = null;
  var time = null;
  
  var analyser = null;
  var data = null;
  var index = null;
  
  function analyse() {
  
      duration = audio.duration / APR;
      length = Math.ceil(duration * FPS);
      width = 4;
      time = 0.0;
  
      data = array(length, width);
      index = 0;
  
      var context = new AudioContext();
  
      analyser = context.createAnalyser();
      analyser.fftSize = FFT_SIZE;
      analyser.smoothingTimeConstant = SMOOTHING;
  
      var source = context.createMediaElementSource(audio);
  
      source.connect(analyser);
      analyser.connect(context.destination);
  
      audio.play();
  
      while (index &lt; length) {
  
          audio.currentTime = time;
  
          frame = getFrame();
          data[index] = frame;
  
          time += INCREMENT;
          index++;
  
      }
  
      audio.pause();
      audio.currentTime = 0;
  
  }
  
  function getFrame() {
  
      var rawFreq = new Uint8Array(analyser.frequencyBinCount);
      analyser.getByteFrequencyData(rawFreq);
  
      var rawTimeDom = new Uint8Array(analyser.fftSize);
      analyser.getByteTimeDomainData(rawTimeDom);
  
      var frame = [];
      frame.push(peak(rawTimeDom), rms(rawTimeDom), low(rawFreq), high(rawFreq));
  
      return frame;
  
  }
  </code></pre>
  
  <p>Output of <code>data</code>:</p>
  
  <pre><code>[
    [128, 128, 100.2, 68.3],
    [128, 128, 100.2, 68.3],
    ...
    [128, 128, 100.2, 68.3]
  ]
  </code></pre>
  
  <p>Also, I should clarify that the reason I am attempting to sample the audio 60 times-per-second is because I will need to display the audio data later at that same rate.</p>