Gagasan autokorelasi adalah untuk memberikan ukuran kesamaan antara sinyal dan dirinya sendiri pada jeda tertentu. Ada beberapa cara untuk mendekatinya, tetapi untuk keperluan deteksi pitch / tempo, Anda dapat menganggapnya sebagai prosedur pencarian. Dengan kata lain, Anda melangkah melalui sampel-sampel sinyal dan melakukan korelasi antara jendela referensi Anda dan jendela yang tertinggal. Korelasi pada "lag 0" akan menjadi maksimum global karena Anda membandingkan referensi dengan salinannya sendiri. Ketika Anda melangkah maju, korelasinya akan berkurang, tetapi dalam kasus sinyal periodik, pada titik tertentu akan mulai meningkat lagi, kemudian mencapai maksimum lokal. Jarak antara "lag 0" dan puncak pertama itu memberi Anda perkiraan pitch / tempo Anda. Cara saya
Menghitung korelasi sampel per sampel dapat menjadi sangat mahal secara komputasi pada tingkat sampel yang tinggi, sehingga biasanya pendekatan berbasis FFT digunakan. Mengambil FFT dari segmen yang menarik, mengalikannya dengan konjugatnya yang kompleks , kemudian mengambil FFT terbalik akan memberi Anda autokorelasi siklik . Dalam kode (menggunakan numpy ):
freqs = numpy.fft.rfft(signal)
autocorr = numpy.fft.irfft(freqs * numpy.conj(freqs))
Efeknya akan mengurangi jumlah noise dalam sinyal (yang tidak berkorelasi dengan dirinya sendiri) relatif terhadap komponen periodik (yang mirip dengan diri mereka sendiri menurut definisi). Mengulangi autokorelasi (yaitu perkalian konjugat) sebelum mengambil transformasi terbalik akan mengurangi kebisingan lebih banyak lagi. Perhatikan contoh gelombang sinus yang dicampur dengan derau putih. Plot berikut menunjukkan gelombang sinus 440 hz, gelombang sinus yang sama "rusak" oleh noise, autokorelasi siklik dari gelombang berisik, dan autokorelasi siklik ganda:
Perhatikan bagaimana puncak pertama dari kedua sinyal autokorelasi terletak tepat di akhir siklus pertama dari sinyal asli. Itulah puncak yang Anda cari untuk menentukan periodisitas (nada dalam hal ini). Sinyal autokorelasi pertama masih sedikit "goyah", jadi untuk melakukan deteksi puncak, beberapa jenis penghalusan akan diperlukan. Autocorrelating dua kali dalam domain frekuensi menyelesaikan hal yang sama (dan relatif cepat). Perhatikan bahwa dengan "goyah", maksud saya bagaimana sinyal terlihat ketika diperbesar, bukan kemiringan yang terjadi di tengah plot. Bagian kedua dari autcorrelation siklik akan selalu menjadi gambar cermin dari bagian pertama, sehingga jenis "celup" adalah khas. Supaya jelas tentang algoritmanya, berikut tampilannya kode:
freqs = numpy.fft.rfft(signal)
auto1 = freqs * numpy.conj(freqs)
auto2 = auto1 * numpy.conj(auto1)
result = numpy.fft.irfft(auto2)
Apakah Anda perlu melakukan lebih dari satu autokorelasi tergantung pada seberapa banyak noise dalam sinyal.
Tentu saja, ada banyak variasi halus pada ide ini, dan saya tidak akan membahas semuanya di sini. Cakupan paling komprehensif yang pernah saya lihat (dalam konteks deteksi pitch) adalah dalam Digital Processing of Speech Signals oleh Rabiner dan Schafer.
Sekarang, apakah autokorelasi akan cukup untuk deteksi tempo. Jawabannya adalah ya dan tidak. Anda bisa mendapatkan informasi tempo (tergantung pada sumber sinyal), tetapi mungkin sulit untuk memahami apa artinya dalam semua kasus. Sebagai contoh, inilah plot dua loop breakbeat, diikuti oleh plot autokorelasi siklik dari seluruh urutan:
Untuk referensi, inilah audio yang sesuai:
Benar saja, ada lonjakan yang bagus tepat di tengah sesuai dengan titik loop, tetapi itu berasal dari pemrosesan segmen yang cukup panjang. Di atas semua itu, jika itu bukan salinan yang tepat (misalnya jika ada instrumentasi dengan itu), lonjakan itu tidak akan bersih. Autokorelasi pasti akan berguna dalam deteksi tempo, tetapi mungkin tidak akan cukup dengan sendirinya untuk bahan sumber yang kompleks. Misalnya, bahkan jika Anda menemukan lonjakan, bagaimana Anda tahu apakah itu ukuran penuh, atau not seperempat, setengah not, atau sesuatu yang lain? Dalam hal ini cukup jelas bahwa itu adalah ukuran penuh, tetapi itu tidak selalu menjadi masalah. Saya sarankan bermain-main dengan menggunakan AC pada sinyal yang lebih sederhana sampai bagian dalam menjadi jelas, lalu mengajukan pertanyaan lain tentang deteksi tempo secara umum (karena ini "lebih besar"