Colpi dei bassi

Si riconoscono quando il livello delle frequenze basse supera di un certo scarto la sua media recente, che si adatta al volume del brano. Qui a ogni colpo il cerchio si ingrandisce, e torna alla dimensione di partenza qualche fotogramma dopo.

    let sound;
let fft;
let media = 0;         // media recente del livello dei bassi
let ultimoColpo = 0;   // fotogramma dell'ultimo colpo

async function setup() {
    createCanvas( 670, 200 );
    sound = await loadSound( 'like_analogue.mp3' );
    fft = new p5.FFT();
    fft.analyzer.normalRange = false;
    sound.connect( fft );
}

function draw() {
    background( 255 );
    let spectrum = fft.analyze();
    let bassi = map( spectrum[0], -100,-20, 0,100, true );
    if (bassi > media + 5) {
        ultimoColpo = frameCount;
    }
    media = lerp( media, bassi, 0.02 );
    if (frameCount - ultimoColpo < 3) {
        circle( width/2, height/2, 150 );
    } else {
        circle( width/2, height/2, 100 );
    }
}

function mousePressed() {
    userStartAudio();
    if (sound.isPlaying()) {
        sound.stop();
    } else {
        sound.play();
    }
}
  

Files

Algoritmo

a ogni fotogramma:                                                draw()
    leggere il livello dei bassi, fra 0 e 100                     map()
    se supera la media recente di più di 5:                       if()
        memorizzare il fotogramma del colpo                       frameCount
    avvicinare un po' la media al livello attuale                 lerp()
    se l'ultimo colpo è di meno di 3 fotogrammi fa:               if()
        disegnare il cerchio grande
    altrimenti:                                                   else
        disegnare il cerchio piccolo

Istruzioni


  

Il livello della prima banda, fino a circa 750 Hz, in decibel come nella slide Energia di una fascia di frequenze, diventa un valore fra 0 e 100. Con true i livelli sotto -100 decibel danno 0, anche prima che il brano parta, quando valgono -Infinity: senza, la media diventerebbe -Infinity e poi NaN, e non si rileverebbe più nessun colpo.


  

Quando il livello dei bassi supera la media di più di 5, memorizza il numero del fotogramma: finché il colpo dura, ultimoColpo si aggiorna a ogni fotogramma.


  

lerp() restituisce un valore intermedio fra i primi due: con 0.02 la media si sposta del 2% verso il livello attuale, e segue lentamente il brano. Una soglia fissa, nei passaggi più forti, segnalerebbe un colpo a ogni fotogramma, e nei più deboli nessuno.


  

Il cerchio resta grande per 3 fotogrammi a partire dall’ultimo colpo, circa un ventesimo di secondo: molti colpi superano la media per un solo fotogramma, e senza questo ritardo l’ingrandimento quasi non si vedrebbe. Con questo brano il cerchio si ingrandisce circa una volta e mezza al secondo.

Variazioni

Con uno scarto più alto restano solo i colpi più forti, e con questo brano gli ingrandimenti passano da circa uno e mezzo a meno di uno ogni due secondi:


  

Con un ritardo più lungo il cerchio resta grande più a lungo, e i colpi vicini si fondono in un solo ingrandimento:


  

Note

La versione precedente di p5.sound.js aveva la classe p5.PeakDetect, che faceva un confronto simile con una soglia. Nella versione 0.4.1 non c’è più, e il confronto va scritto direttamente nel codice dello sketch.