Search code examples
javascriptaudiohtml5-audioweb-audio-api

Not getting frequency data in web audio using getFloatFrequencyData with live input


Working example: https://codepen.io/anon/pen/RGmVgG

I have code working that gets live mic input data and outputs it to the system default speaker. I've verified I'm getting data.

I then am trying to get the frequency data, but it returns as an array of -Infinity (or -100 in Firefox).

I've been through the MDN docs for this and seem to have everything in place, but I'm not getting the frequency data. Any idea what I need to do different?

html

Audio Data:
<div id="audio-data"></div>

Frequency Data:
<div id="frequency-data"></div>

js

window.addEventListener('load', () => {
  navigator.mediaDevices.getUserMedia({audio: true})
    .then((stream) => {
      const audioDataDisplay = document.querySelector('#audio-data');
      const frequencyDataDisplay = document.querySelector('#frequency-data');
      const context = new AudioContext();
      const source = context.createMediaStreamSource(stream);
      const processor = context.createScriptProcessor(256, 1, 1);

      source.connect(processor);
      processor.connect(context.destination);

      // route default microphone audio to default speaker output for system
      // display live audio buffer data
      processor.onaudioprocess = (data) => {
        const channelCount = data.outputBuffer.numberOfChannels;

        for (let i = 0; i < channelCount; i++) {
          const inputChannelData = data.inputBuffer.getChannelData(i);
          const outputChannelData = data.outputBuffer.getChannelData(i);

          for (let j = 0; j < inputChannelData.length; j++) {
            outputChannelData[j] = inputChannelData[j];
          }

          audioDataDisplay.innerHTML = outputChannelData;
        }
      }

      // analyze the frequency data and display data
      // only shows as an array of -Infinity in Chrome, -100 in Firefox.
      const analyser = context.createAnalyser();
      const dataArray = new Float32Array(analyser.frequencyBinCount);

      setInterval(() => {
        analyser.getFloatFrequencyData(dataArray);
        frequencyDataDisplay.innerHTML = dataArray;
      }, 1000);
  });
});

Solution

  • You're never connecting anything to your analyser node. Add something like

        source.connect(analyser);
    

    after creating the analyser.