It does exactly what you think it does, but the specific implementation on that site is not great for seeing that.
The values are mapped differently than is nescessary for seeing changes in pitch between high and low vocal range because the range is mapped linearly, not logrithmically. If you were to map each frequency bin in a logarithmic way you would get a far more useful diagram. Right now the right hand 3/4 of the visualizer is showing from 5000hz to 20000hz (roughly), which contains very very little data in an audio signal compared to 0-5000hz. The root frequency of the human voice (and most instruments) occupies mostly between 100-1000hz. There are harmonics above that, but at reducing amplitudes the higher you get.
I've tweaked the code to tell you the peak frequency and the size of each bucket. Use this app.js: https://puu.sh/Izcws/ded6aae55b.js - you can use a tone generator on your phone to see how accurate it is. https://puu.sh/Izcx3/d5a9d74764.png
The way the code works is it calculates how big each bucket is as described in my answer with var bucketSize = 1 / (analyser.fftSize / analyser.context.sampleRate); (and adds two spans to show the data) and then while drawing each bar calculate which bar is the biggest, and then multiply the size of each bucket by which bucket is the biggest to get the peak frequency (and write it in el2). You can play with the fftSize and see why using a small value will not work at all for determining whether you are playing A2(110 Hz) or A2#(116.5 Hz).
From https://stackoverflow.com/a/43369065/13801789:
I believe I understand what you mean exactly. The problem is not with your code, it is with the FFT underlying getByteFrequencyData. The core problem is that musical notes are logarithmically spaced while the FFT frequency bins are linearly spaced.
Notes are logarithmically spaced: The difference between consecutive low notes, say A2(110 Hz) and A2#(116.5 Hz) is 6.5 Hz while the difference between the same 2 notes on a higher octave A3(220 Hz) and A3#(233.1 Hz) is 13.1 Hz.
FFT bins are linearly spaced: Say we're working with 44100 samples per second, the FFT takes a window of 1024 samples (a wave), and multiplies it first with a wave as long as 1024 samples (let's call it wave1), so that would be a period of 1024/44100=0.023 seconds which is 43.48 Hz, and puts the resulting amplitude in the first bin. Then it multiplies it with a wave with frequency of wave1 * 2, which is 86.95 Hz, then wave1 * 3 = 130.43 Hz. So the difference between the frequencies is linear; it's always the same = 43.48, unlike the difference in musical notes which changes.
This is why close low notes will be bundled up in the same bin while close high notes are separated. This is the problem with FFT's frequency resolution. It can be solved by taking windows bigger than 1024 samples, but that would be a trade off for the time resolution.