Mi piacerebbe scrivere una semplice applicazione C # per monitorare l'audio line-in e darmi i battiti al minuto correnti (beh, la media mobile).
Ho visto questo articolo di gamedev , e questo non mi è stato di alcun aiuto. Ho attraversato e ho cercato di implementare quello che stava facendo, ma non funzionava.
So che ci devono essere tonnellate di soluzioni per questo, perché molti software DJ lo fanno, ma non ho alcuna fortuna nel trovare una libreria open source o le istruzioni per farlo da solo.
Calcola un powerspectrum con una finestra scorrevole FFT: Prendi 1024 campioni:
double[] signal = stream.Take(1024);
Alimentalo con un algoritmo FFT:
double[] real = new double[signal.Length];
double[] imag = new double[signal.Length);
FFT(signal, out real, out imag);
Otterrai una parte reale e una parte immaginaria. NON buttare via la parte immaginaria. Fai lo stesso con la parte reale dell'immaginario. Mentre è vero che la parte immaginaria è più sfasata rispetto al reale, essa contiene ancora il 50% delle informazioni sullo spettro.
MODIFICARE:
Calcola la potenza rispetto all'ampiezza in modo da avere un numero elevato quando è forte e vicino a zero quando è silenzioso:
for (i=0; i < real.Length; i++) real[i] = real[i] * real[i];
Allo stesso modo per la parte immaginaria.
for (i=0; i < imag.Length; i++) imag[i] = imag[i] * imag[i];
Ora hai uno spettro di potenza per gli ultimi 1024 campioni. Dove la prima parte dello spettro è le basse frequenze e l'ultima parte dello spettro sono le alte frequenze .
Se vuoi trovare BPM nella musica popolare dovresti probabilmente concentrarti sul basso. È possibile rilevare l'intensità del basso sommando la parte inferiore dello spettro di potenza. Quali numeri utilizzare dipende dalla frequenza di campionamento:
double bassIntensity = 0;
for (i=8; i < 96; i++) bassIntensity += real[i];
Ora fai lo stesso, ma sposta la finestra 256 campioni prima di calcolare un nuovo spettro. Ora finisci col calcolare il bassIntensity per ogni 256 campioni.
Questo è un buon input per la tua analisi BPM. Quando il basso è silenzioso non hai un ritmo e quando è forte hai un ritmo.
In bocca al lupo!
C'è un eccellente progetto chiamato Dancing Monkeys, che genera proceduralmente passi di danza DDR dalla musica. Gran parte di ciò che fa si basa su un'analisi di battimento (necessariamente molto accurata), e il loro articolo di progetto contiene molti dettagli che descrivono i vari algoritmi di rilevamento dei battiti e la loro idoneità al compito. Includono riferimenti ai documenti originali per ciascuno degli algoritmi. Hanno anche pubblicato il codice MATLAB per la loro soluzione. Sono sicuro che tra quelli puoi trovare quello che ti serve.
È tutto disponibile qui: http://monket.net/dancing-monkeys-v2/Main_Page
Non che io abbia la minima idea di come implementarlo, ma da un punto di vista dell'ingegneria audio dovresti prima filtrare. Colpi di batteria grossi sarebbero i primi a controllare. Un filtro passa-basso che ti dà qualcosa sotto i 200Hz dovrebbe darti un'immagine chiara della cassa. Potrebbe anche essere necessario un cancello per ripulire qualsiasi disordine da altri strumenti con armoniche così basse.
Il prossimo a controllare sarebbero i colpi di rullante. Dovresti equalizzare questo. Il "crack" di un rullante è di circa 1.5kHz dalla memoria, ma avresti bisogno di chiudere definitivamente questo.
La prossima sfida sarebbe quella di elaborare un algoritmo per i ritmi funky. Come troveresti automaticamente il battito 1? Immagino che tu tenga traccia dei battiti precedenti e usi un modello che corrisponda a qualcosa-o-altro. Quindi, probabilmente avrai bisogno di alcune barre per trovare con precisione il ritmo. Poi ci sono problemi di temporizzazione come 4/4, 3/4, 6/8, wow, non riesco a immaginare cosa sarebbe richiesto per farlo in modo accurato! Sono sicuro che varrà qualcosa di serio per le aziende di hardware/software audio.
Questo non è affatto un problema facile. Proverò a darti solo una panoramica.
Quello che potresti fare è qualcosa di simile al seguente:
Una trasformata di Fourier è fondamentalmente un modo per calcolare la forza di tutte le frequenze presenti nel segnale. Se lo fai sopra il segnale "bloccato", la frequenza del battito sarà probabilmente la più forte.
Forse è necessario applicare prima un filtro, per concentrarsi su frequenze specifiche (come il basso) che di solito contengono la maggior parte delle informazioni sul BPM.
Ho trovato questa libreria che sembra avere un'implementazione piuttosto solida per il rilevamento di Beats per Minute . http://soundtouchdotnet.codeplex.com/
Si basa su http://www.surina.net/soundtouch/index.html che viene utilizzato in molti progetti DJ http://www.surina.net/soundtouch/applications.html
Prima di tutto, ciò che Hallgrim sta producendo non è la funzione di densità spettrale di potenza. Periodicità statistiche in qualsiasi segnale possono essere evidenziate attraverso una funzione di autocorrelazione. La trasformata di Fourier del segnale di autocorrelazione è la densità spettrale di potenza. Picchi dominanti nella PSD diversa da 0 Hz corrisponderanno alla periodicità effettiva nel segnale (in Hz) ...
Ti consiglio di controllare la libreria audio BASS e il wrapper BASS.NET. Ha una classe BPMCounter integrata.
Dettagli per questa specifica funzione sono disponibili su http://bass.radio42.com/help/html/0833aa5a-3be9-037c-66f2-9adfd42a8512.htm .
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 divisi per il tempo.