36

I've used the FFT data from the Analyser node using the getByteFrequencyData method in the Web Audio API to create a spectrum visualizer as shown below:

Spectrum Visualizer

In this instance I have 256 bins of data. What exactly do the numbers in this correspond to? Is it the decibel level of each frequency component. If so how do I know what the value of the frequency of each bin corresponds to?

I would like to know so I can experiment in building a graphic eq and so would like to know at which points to indicate the filter bands. Ideally I'd like to represent frequencies from 20Hz to 20kHz and plot intervals between those accordingly.

Thanks for any help.

RobotEyes
  • 4,929
  • 6
  • 42
  • 57

3 Answers3

39

yes,getByteFrequencyData results in a normalized array of values between 0 and 255. (it copies the data to the array it gets passed-in).

the frequency bands are split equally, so each element N of your array corresponds to:

N * samplerate/fftSize

so, the first bin is 0.
and, assuming a samplerate of 44100 and a <analyzerNode>.fftSize of 512 the second would be: 86.13 Hz, and so on...

you will find these two questions and answers useful, on dsp and on SO:

Note that the length of your sampledata is half the <analyzerNode>.fftSize, effectively limiting the frequency-range to half the samplerate.

Community
  • 1
  • 1
kr1
  • 7,225
  • 1
  • 26
  • 29
  • getByteFrequencyData doesn't return anything; rather, it copies the frequency data values (0-255) _into_ the unsigned array (Uint8Array() in javascript) that you pass into the method as a parameter. [W3C Draft – Web Audio API – getByteFrequencyData](https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AnalyserNode). Just in case anyone gets caught trying to use some form of returned value from this method call... – Danny Bullis Mar 28 '13 at 18:31
  • rock on! Not trying to be nit-picky :] – Danny Bullis Mar 28 '13 at 19:00
  • 18
    BTW default sample rate may be different. E.g. for me it is 48000. One should check `audioContext.sampleRate` for certain value. – kirilloid Aug 25 '13 at 03:07
  • 5
    For anyone looking for more information, half of the sample rate is called the Nyquist Frequency. – Ian Hunter Jul 08 '14 at 14:05
  • What does "the first bin is 0" mean? It represents the amount of 0Hz in the signal? So is it just a measure of the overall amplitude? And if so would it normally be excluded in a visualisation of frequencies? – rob Mar 10 '17 at 03:20
  • 1
    0Hz is, indeed, the DC offset - so it's a number that if you subtract it from your original signal would make that signal zero-mean. It's not amplitude in the usual sense for for audio. – Arunas May 16 '17 at 22:01
  • 1
    This doesn't make any sense, because if (N * samplerate/fftSize) is the formula then the first bin (array index 0) should always have a 0 value since 0 * anything is 0. I definitely get values in the first bin. (N +1 * samplerate/fftSize) seems more like it, but that means the first bin is 86.13hz. – Cliff Hall Sep 25 '17 at 20:20
6

With 256 bins, each one will be ~86 Hz apart (44100 kHz sample rate / fftSize, where fftSize is twice the number of bins). So you start at zero and go up in 86 Hz increments from there.

The actual values in the bins are just a representation of how much of each frequency is present in the signal (i.e. how "loud" the frequency is).

Kevin Ennis
  • 14,226
  • 2
  • 43
  • 44
  • the web audio api returns a number of bins which is half the fftSize. so, IMHO you should divide by `bins.length * 2` or better using `fftSize` directly, see also my answer. – kr1 Feb 09 '13 at 16:17
4

TL;DR I suppose it producing dBu


if anyone, just as me not being an audio engineer, struggling trying to figure out a proper scale (what it actually means) for a results from getByteFrequencyData/getFloatFrequencyData here is my findings:

  • first check out this web audio spec there we can find an equation to go from a frequency data to dB value itself

Y[k]=20log10X^[k]

and see that dBu computation looks quite similar dBu

  • previously I've watched this video to understand the basics

  • so build a scale to display dB as dBu with zero pointing to -4dBu (I hope this make sense) dB scale

  • and now attempt to validate this scale with a proper stream. so I could produce -24 dBFS (-18dBFS = +4dBu this is suppose to be a standard?) signal which is should be at -18 + -24 + 4 - -4 = -34 at scale above. and this is what actually I'm getting in the end enter image description here

Bender
  • 617
  • 6
  • 17