I asked a question similar to this earlier, but it did not solve my issue and was explained poorly. This time I've made illustrations to hopefully explain better.
I have a simple frequency spectrum analyser for my audio player. The frequencies are stored in an array that gets updated on each requestAnimationFrame, the array looks like this:
fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);
Read more about getByteFrequencyData here.
So this works fine however I would like the frequencies to be evenly spaced throughout the spectrum. Right now it's displaying linear frequencies:
As you can see, the dominating frequency range here is the Treble (High end), and the most dominated frequency range is the bass range (low end). I want my analyser presented with evenly distributed frequency ranges like this:
Here you see the frequencies evenly spaced across the analyser. Is this possible?
The code I used for generating the analyser looks like this:
// These variables are dynamically changed, ignore them.
var canbars = 737
var canmultiplier = 8
var canspace = 1
// The analyser
var canvas, ctx, source, context, analyser, fbc_array, bars, bar_x,
bar_width, bar_height;
function audioAnalyserFrame() {
'use strict';
var i;
canvas.width = $('analyser-').width();
canvas.height = $('analyser-').height();
ctx.imageSmoothingEnabled = false;
fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
ctx.fillStyle = "white"; // Color of the bars
bars = canbars;
for (i = 0; i < bars; i += canmultiplier) {
bar_x = i * canspace;
bar_width = 2;
bar_height = -3 - (fbc_array[i] / 2);
ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
}
window.requestAnimationFrame(audioAnalyserFrame);
}
function audioAnalyserInitialize() {
'use strict';
var analyserElement = document.getElementById('analyzer');
if (analyserElement !== null && audioViewIsCurrent() === true) {
if (analyserInitialized === false) {
context = new AudioContext();
source = context.createMediaElementSource(audioSource);
} else {
analyser.disconnect();
}
analyser = context.createAnalyser();
canvas = analyserElement;
ctx = canvas.getContext('2d');
source.connect(analyser);
analyser.connect(context.destination);
if (analyserInitialized === false) {
audioAnalyserFrame();
}
analyserInitialized = true;
analyser.smoothingTimeConstant = 0.7;
}
}
Take note that I am skipping 8 bars (See canmultiplier at the top) in the for loop (If I don't, the other half of the analyser gets rendered outside the canvas because it's too big.) I don't know if this is also what could be causing the inconsistent frequency ranges.

