[Algorithm] Come rilevare il BPM di una canzone in PHP


Answers

Le parole chiave da cercare sono "Beat Detection", "Beat Tracking" e "Music Information Retrieval". Ci sono molte informazioni qui: http://www.music-ir.org/

C'è un (forse) contest annuale chiamato MIREX dove diversi algoritmi vengono testati sulle loro prestazioni di rilevamento dei battiti.

http://nema.lis.illinois.edu/nema_out/mirex2010/results/abt/mck/

Questo dovrebbe darti una lista di algoritmi da testare.

Un algoritmo classico è Beatroot (google it), che è bello e facile da capire. Funziona così:

  1. FFT a breve tempo la musica per ottenere un sonogramma.
  2. Sommare gli incrementi di magnitudine su tutte le frequenze per ciascun passo temporale (ignorare le diminuzioni). Questo ti dà una funzione variabile nel tempo 1D chiamata "flusso spettrale".
  3. Trova i picchi usando un vecchio algoritmo di rilevamento dei picchi. Questi sono chiamati "onset" e corrispondono all'inizio dei suoni nella musica (inizi di note, colpi di batteria, ecc.).
  4. Costruire un istogramma di intervalli di interferenza (IOI). Questo può essere usato per trovare i tempi probabili.
  5. Inizializza un insieme di "agenti" o "ipotesi" per il risultato del tracciamento del battito. Alimenta questi agenti gli insiemi uno alla volta in ordine. Ogni agente tiene traccia dell'elenco di insiemi che sono anche i battiti e la stima del tempo corrente. Gli agenti possono accettare gli insiemi, se si adattano strettamente al loro ultimo ritmo e tempo tracciati, ignorarli se sono molto diversi, o generare un nuovo agente se sono in mezzo. Non tutti i battiti richiedono un esordio - gli agenti possono interpolare.
  6. A ogni agente viene assegnato un punteggio in base a quanto è precisa la sua ipotesi: se tutte le sue battute sono alte, ottiene un punteggio più alto. Se sono tutti regolari ottiene un punteggio più alto.
  7. L'agente con il punteggio più alto è la risposta.

Svantaggi di questo algoritmo nella mia esperienza:

  • Il rilevamento del picco è piuttosto ad-hoc e sensibile ai parametri di soglia e quant'altro.
  • Alcuni brani musicali non hanno un'evidente differenza sui beat. Ovviamente non funzionerà con quelli.
  • Difficile sapere come risolvere il problema 60bpm-vs-120bpm, in particolare con il monitoraggio dal vivo!
  • Elimina molte informazioni usando solo un flusso spettrale 1D. Penso che si possa fare molto meglio con alcuni flussi spettrali a banda limitata (e forse uno a banda larga per la batteria).

Ecco una demo di una versione live di questo algoritmo, che mostra il flusso spettrale (linea nera nella parte inferiore) e gli offset (cerchi verdi). Vale la pena considerare il fatto che il ritmo viene estratto solo dalle cerchie verdi. Ho riprodotto gli offset proprio come i clic e, sinceramente, non credo di poter sentire il battito da loro, quindi in qualche modo questo algoritmo è migliore delle persone con rilevamento dei battiti. Penso che la riduzione a un segnale così basso dimensionalmente sia il suo passo debole.

Fastidiosamente ho trovato un buon sito con molti algoritmi e codice per il rilevamento dei battiti qualche anno fa. Tuttavia, non sono riuscito a rifarlo.

Modifica: Trovato!

Ecco alcuni ottimi link che dovrebbero iniziare:

http://marsyasweb.appspot.com/

http://www.vamp-plugins.org/download.html

Question

Come si può determinare programmaticamente il tempo / BPM di una canzone? Quali algoritmi sono comunemente usati e quali considerazioni devono essere fatte?




Per ripubblicare la mia risposta: il modo più semplice per farlo è di fare in modo che l'utente tocchi un pulsante a ritmo con il ritmo e contenga il numero di tocchi diviso per il tempo.




Immagino che questo sarà più facile nella musica da ballo 4-4, poiché dovrebbe esserci un singolo tonfo a bassa frequenza circa due volte al secondo.




Esegui una trasformazione di Fourier e trova picchi nello spettro di potenza. Stai cercando picchi al di sotto del limite di 20 Hz per l'udito umano. Immagino che tipicamente nell'intervallo 0.1-5ish Hz sia generoso.

QUINTA domanda che potrebbe essere d'aiuto: libreria di rilevamento audio Bpm

Inoltre, ecco una delle numerose domande di "peak finding" su SO: rilevamento del picco del segnale misurato

Modifica: non che io esegua l'elaborazione audio. È solo un'ipotesi basata sul fatto che stai cercando una proprietà del file frequenza del file ...

un'altra modifica: vale la pena notare che i formati di compressione lossy come mp3, archiviano i dati del dominio di Fourier piuttosto che i dati del dominio del tempo in primo luogo. Con un po 'di intelligenza, puoi risparmiare un grosso calcolo ... ma guarda il commento di cobbal.




Ci sono diversi metodi per ottenere il BPM, ma quello che trovo più efficace è lo "spettro del battito" (descritto qui ). Questo algoritmo calcola una matrice di similarità confrontando ogni breve campione della musica con tutti gli altri. Una volta calcolata la matrice di similarità è possibile ottenere una somiglianza media tra ciascuna coppia di campioni {S (T); S (T + 1)} per ciascun intervallo di tempo T: questo è lo spettro delle battute. Il primo picco alto nello spettro delle battute è il più delle volte la durata del battito. La parte migliore è che puoi anche fare cose come la struttura della musica o l'analisi del ritmo.




L'area di ricerca generale che ti interessa è chiamata MUSIC INFORMATION RETRIEVAL

Ci sono molti algoritmi diversi che fanno questo, ma sono tutti centrati attorno alla RILEVAZIONE ONSET.

Il rilevamento dell'inizio misura l'inizio di un evento, l'evento in questo caso è una nota in riproduzione. È possibile cercare modifiche nella trasformata di Fourier ponderata (contenuto ad alta frequenza) per cercare grandi cambiamenti nel contenuto spettrale. (Differenza spettrale). (ci sono un paio di documenti che ti consiglio di esaminare più in basso). Una volta applicato un algoritmo di rilevamento dell'inizio, scegli dove sono i battiti tramite la soglia.

Esistono vari algoritmi che è possibile utilizzare una volta ottenuta la localizzazione del tempo in quel momento. Puoi trasformarlo in un treno di impulsi (creare un segnale che è zero per tutti i tempi e 1 solo quando il tuo battito accade) quindi applicare una FFT a quella e BAM ora hai una frequenza di offset al picco più grande.

Ecco alcuni documenti per guidarti nella giusta direzione:

http://www.elec.qmul.ac.uk/people/juan/Documents/Bello-TSAP-2005.pdf

http://bingweb.binghamton.edu/~ahess2/Onset_Detection_Nov302011.pdf

Ecco un'estensione di ciò che alcune persone stanno discutendo:

Qualcuno ha menzionato la possibilità di applicare un algoritmo di apprendimento automatico: in pratica, raccogliere una serie di funzioni dalle funzioni di rilevamento delle fasi iniziali (menzionate sopra) e combinarle con il segnale grezzo in una rete neurale / regressione logistica e imparare ciò che rende un battito un battito.

guarda il dott. Andrew Ng, ha lezioni gratuite di apprendimento automatico dalla Stanford University online (non le lunghe lezioni video, c'è in realtà un corso online a distanza)