L'idea di autocorrelazione è quella di fornire una misura di somiglianza tra un segnale e se stesso in un determinato ritardo. Esistono diversi modi per affrontarlo, ma ai fini del rilevamento di tonalità / tempo, puoi considerarlo come una procedura di ricerca. In altre parole, si passa attraverso il segnale campione per campione ed si esegue una correlazione tra la finestra di riferimento e la finestra ritardata. La correlazione a "ritardo 0" sarà il massimo globale perché stai confrontando il riferimento con una copia testuale di se stesso. Man mano che avanzi, la correlazione diminuirà necessariamente, ma nel caso di un segnale periodico, ad un certo punto inizierà nuovamente ad aumentare, quindi raggiungerà un massimo locale. La distanza tra "lag 0" e quel primo picco ti dà una stima del tuo pitch / tempo. Il modo in cui io
Il calcolo delle correlazioni campione per campione può essere molto costoso dal punto di vista computazionale a frequenze di campionamento elevate, quindi in genere viene utilizzato un approccio basato su FFT. Prendere la FFT del segmento di interesse, moltiplicandolo per il suo coniugato complesso , quindi prendere la FFT inversa ti darà l' autocorrelazione ciclica . Nel codice (usando numpy ):
freqs = numpy.fft.rfft(signal)
autocorr = numpy.fft.irfft(freqs * numpy.conj(freqs))
L'effetto sarà di ridurre la quantità di rumore nel segnale (che non è correlato con se stesso) rispetto alle componenti periodiche (che sono simili a loro stesse per definizione). La ripetizione dell'autocorrelazione (ovvero la moltiplicazione del coniugato) prima di effettuare la trasformazione inversa ridurrà ulteriormente il rumore. Considera l'esempio di un'onda sinusoidale mista a rumore bianco. Il diagramma seguente mostra un'onda sinusoidale da 440 Hz, la stessa onda sinusoidale "corrotta" dal rumore, l'autocorrelazione ciclica dell'onda rumorosa e la doppia autocorrelazione ciclica:
Notare come il primo picco di entrambi i segnali di autocorrelazione si trova esattamente alla fine del primo ciclo del segnale originale. Questo è il picco che stai cercando per determinare la periodicità (tono in questo caso). Il primo segnale di autocorrelazione è ancora un po '"sinuoso", quindi per eseguire il rilevamento di picco sarebbe necessario un qualche tipo di livellamento. L'autocorrelazione due volte nel dominio della frequenza realizza la stessa cosa (ed è relativamente veloce). Nota che per "wiggly" intendo come appare il segnale quando ingrandito, non il calo che si verifica al centro della trama. La seconda metà dell'autocorrelazione ciclica sarà sempre l'immagine speculare della prima metà, quindi quel tipo di "tuffo" è tipico. Giusto per essere chiari sull'algoritmo, ecco come sarebbe il codice:
freqs = numpy.fft.rfft(signal)
auto1 = freqs * numpy.conj(freqs)
auto2 = auto1 * numpy.conj(auto1)
result = numpy.fft.irfft(auto2)
La necessità di eseguire più di una autocorrelazione dipende dalla quantità di rumore presente nel segnale.
Naturalmente, ci sono molte sottili variazioni su questa idea e non ho intenzione di approfondirle tutte qui. La copertura più completa che ho visto (nel contesto del rilevamento del tono) è in Digital Processing of Speech Signals di Rabiner e Schafer.
Ora, se l'autocorrelazione sarà sufficiente per il rilevamento del tempo. La risposta è sì e no. È possibile ottenere alcune informazioni sul tempo (a seconda del segnale sorgente), ma potrebbe essere difficile capire cosa significhi in tutti i casi. Ad esempio, ecco un diagramma di due anelli di un breakbeat, seguito da un diagramma dell'autocorrelazione ciclica dell'intera sequenza:
Per riferimento, ecco l'audio corrispondente:
Abbastanza sicuro, c'è un bel picco nel mezzo corrispondente al punto del loop, ma è venuto dall'elaborazione di un segmento piuttosto lungo. Inoltre, se non fosse una copia esatta (ad esempio se fosse presente una strumentazione), quel picco non sarebbe altrettanto pulito. L'autocorrelazione sarà sicuramente utile nel rilevamento del tempo, ma probabilmente non sarà sufficiente da sola per materiale sorgente complesso. Ad esempio, anche se trovi un picco, come fai a sapere se è una misura completa, o una nota da un quarto, una mezza nota o qualcos'altro? In questo caso è abbastanza chiaro che si tratta di una misura completa, ma non sarà sempre così. Suggerirei di giocare con l'uso di AC su segnali più semplici fino a quando i meccanismi interni non saranno chiari, quindi fare un'altra domanda sul rilevamento del tempo in generale (poiché è un "più grande"