Search code examples
javascripthtml5-canvasweb-audio-api

How (if at all) can AnalyserNode be used to analyze a whole audio file, and get the data necessary for visualization?


In particular, I am interested in the AnalyserNode.getFloatTimeDomainData() method.

Can I use this method, to create a waveform, that represents the entire audio file?

Or is AnalyserNode only for audio streams?

The MDN documentation says:

The AnalyserNode interface represents a node able to provide real-time frequency and time-domain analysis information. It is an AudioNode that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations.

https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode

All examples seem to use AudioBuffer.getChannelData() for the purpose of getting data for the visualization of an entire audio file. As in this article:

https://css-tricks.com/making-an-audio-waveform-visualizer-with-vanilla-javascript/

From the article:

const filterData = audioBuffer => {
  const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
  const samples = 70; // Number of samples we want to have in our final data set
  const blockSize = Math.floor(rawData.length / samples); // the number of samples in each subdivision
  const filteredData = [];
  for (let i = 0; i < samples; i++) {
    let blockStart = blockSize * i; // the location of the first sample in the block
    let sum = 0;
    for (let j = 0; j < blockSize; j++) {
      sum = sum + Math.abs(rawData[blockStart + j]) // find the sum of all the samples in the block
    }
    filteredData.push(sum / blockSize); // divide the sum by the block size to get the average
  }
  return filteredData;
}

Solution

  • You say, in the subject, that you have the whole file. If that's the case, you can decode the file (decodeAudioData) and you'll get an AudioBuffer with all of the samples that you can then use for visualization.

    If you cannot decode the entire file into memory, you'll have to use a different method, and AnalyserNode will probably not work because it's asynchronous so you may not get all of the samples or you may get duplicates. If this is not acceptable, you'll have to use, perhaps, a MediaStreamAudioSourceNode connected to a ScriptProcessorNode or AudioWorkletNode to get the time-domain data that you want.