Visualise the "Timeline" of a song in p5.js

43 views Asked by At

So, I’m trying to visualise sound in a grid, by changing the size of forms according to the bass, treble and mids levels.

But what i want to to, is basically divide the song in as many steps as I have fields in the grid and get the level for every of these steps.

How can I say when I have 25 fields, that I want the duration of the song divided into 25 parts and get the level for every part?

I’m completely lost, I don’t even know what to search for and if anyone could point me in a direction I would be super glad.

This is the code I used to draw the fields and its working fine, but of course, it only shows me the current level in every field.

function draw() {
    background(0);
    var spectrum = fft.analyze();
    var bass = fft.getEnergy("bass");
    var treble = fft.getEnergy("treble");
    var mid = fft.getEnergy("mid");

    for (var x = 0; x <= width; x += width/10) {
        for (var y = 0; y <= height; y += height/10) {

            //BASS
            var bassAmp = map(bass, 0, 512, 0, width/10);
            noFill();
            stroke(255);
            rect(x,y,bassAmp,bassAmp);

            //TREBLE
            var trebleAmp = map(treble, 0, 512, 0, width/10);
            noFill();
            stroke(255);
            rect(x,y,trebleAmp,trebleAmp);

            //MID
            var midAmp = map(mid, 0, 512, 0, width/10);
            noFill();
            stroke(255);
            rect(x,y,midAmp,midAmp);
        }
    }
1

There are 1 answers

0
James On

You can specify low and high frequencies when you call getEnergy to specify a "band". You will need to divide the audible spectrum into "n" frequency bands that you want.

Here's an example of one approach.

const frequencyRanges = [
  [40, 100],
  [100, 200],
  [200, 400],
  //etc
];


function draw() {
    background(0);
    var spectrum = fft.analyze();
    
    const amps = frequencyRanges.map(([low, high]) => fft.getEnergy(low, high));
    let whichAmp = 0;

    for (var x = 0; x <= width; x += width/10) {
        for (var y = 0; y <= height; y += height/10) {
           let amp = map(amps[whichAmp], 0, 512, 0, width / 10);
           noFill();
           stroke(255);
           rect(x,y,amp,amp);
           whichAmp++;
           if (whichAmp === amps.length) whichAmp = 0;
        }
    }
}