Autokorelasi dalam analisis audio

11

Saya membaca tentang Autocorrelation , tetapi saya tidak yakin saya mengerti persis bagaimana cara kerjanya dan output apa yang harus saya harapkan. Apakah saya benar dalam berpikir bahwa saya harus memasukkan sinyal saya ke fungsi AC dan memiliki input jendela geser. Setiap jendela (dari 1024 sampel, misalnya) akan menghasilkan koefisien antara -1 dan 1. Tanda hanya menyatakan jika garis ke atas atau ke bawah dan nilainya menyatakan seberapa kuat korelasinya. Untuk kesederhanaan, katakanlah saya tidak memiliki tumpang tindih dan hanya memindahkan sampel jendela 1024 setiap kali. Dalam sampel 44100, akankah saya mendapatkan 43 koefisien dan apakah saya harus menyimpan semuanya?

Katakanlah saya melakukan ini untuk sinyal 200 detik, memberi saya 8600 koefisien. Bagaimana saya menggunakan koefisien ini untuk mendeteksi pengulangan dan, pada gilirannya, tempo? Haruskah saya membuat semacam jaringan saraf untuk mengelompokkan mereka, atau apakah itu berlebihan?

Terima kasih atas bantuannya.

XSL
sumber
4
Misalkan sampel Anda adalah . Bisakah Anda memberi tahu kami apa fungsi AC Anda kembali? Jawaban yang mungkin adalah: "Mengembalikan " atau "Mengembalikan angka mana "atau" Ini mengembalikan angka mana ". Ketiga jawaban yang disarankan ini kompatibel dengan gagasan autokorelasi. x [ 1 ] , x [ 2 ] , ... , x [ 1024 ] Σ 1024 i = 1 ( x [ i ] ) 2 1024 R [ k ] R [ k ] = Σ 1024 - k i = 1 x [ i ] x [ i + k ] 1024 R [ k1024x[1],x[2],...,x[1024]saya=11024(x[saya])21024R[k]R[k]=saya=11024-kx[saya]x[saya+k]1024R [ k ] = 1024 - k i = 1 x [ i ] x [ i + k ] + k i = 1 x [ 1024 - k + i ] x [ i ]R[k]R[k]=saya=11024-kx[saya]x[saya+k]+saya=1kx[1024-k+saya]x[saya]
Dilip Sarwate
Hei Dilip, terima kasih atas bantuannya. Saya belum mengimplementasikan fungsi AC, saya hanya mencoba memahami teori dulu. Persamaan pertama terlihat paling mudah tetapi apakah data perlu dinormalisasi terlebih dahulu?
XSL
1
Berikut ini contohnya: gist.github.com/255291#L62
endolith

Jawaban:

23

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:

Autokorelasi

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:

Autokorelasi Breakbeat

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"

datageist
sumber
2
Tunggu dulu, apakah itu autokorelasi sinyal audio itu sendiri? Itu tentu tidak terlalu berguna untuk deteksi tempo apa pun kecuali loop digital. Autokorelasi beberapa amplop RMS seharusnya bekerja lebih baik secara umum, lebih disukai untuk beberapa pita frekuensi secara terpisah.
leftaroundabout
1
Autokorelasi dari STFT dalam arah waktu bekerja dengan cukup baik, asalkan musik memiliki beberapa jenis beat. Ini pada dasarnya sama dengan menjalankan autokorelasi banyak pita frekuensi dan kemudian menjumlahkannya bersama-sama.
endolith
2
@leftroundabout Benar, ada sejumlah hal yang perlu dilakukan untuk deteksi tempo (pre, post processing) selain autocorrelation dengan sendirinya. Saya terutama menanggapi kalimat pertama dari pertanyaan OP (yaitu "bagaimana cara kerja autokorelasi"), kemudian menyarankan dia mengajukan pertanyaan lain tentang deteksi tempo, karena proses lain akan dilibatkan.
datageist
@ endolith apa maksudmu di sini Autocorrelation of the STFT in the time direction? Khususnya bagian arah waktu
popctrl
1
@popctrl Berarti untuk menghitung autokorelasi setiap baris STFT
endolith
3

Kedengarannya seperti Anda ingin menggunakan autocorrelation untuk melakukan deteksi ketukan. Anda dapat melakukan ini, tetapi saya sarankan Anda secara besar-besaran mengurangi audio Anda. Anda sedang mencari sinyal antara 1 dan 3 Hz (60 bpm hingga 180 bpm) sehingga Anda tidak perlu atau menginginkan resolusi 44100 hz. Autokorelasi yang dikomputasi dan dinormalisasi dengan benar adalah 1,0 pada lag 0 (sinyal berkorelasi sempurna dengan dirinya sendiri). Untuk sinyal periodik, ac turun di bawah nol, kemudian muncul kembali pada puncak di lag yang sesuai dengan frekuensi fundamental, dengan puncak yang lebih kecil pada harmonisa. Anda harus memilih rentang yang masuk akal untuk mencari puncak ini. Untuk noise, autocorrelation turun dan pada dasarnya pipih dalam coretan di sekitar nol. Sebagai aturan praktis, jika Anda memiliki puncak> 0,5 di AC dinormalisasi, Anda memiliki sinyal periodik.

Tagihan
sumber
1

Korelasi otomatis hanyalah korelasi silang dari sinyal dengan dirinya sendiri. Cara mudah untuk menghitungnya adalah dengan melakukan konvolusi antara sinyal asli dan versi sinyal yang dibalik waktu. Jika Anda memiliki sinyal yang panjangnya 1000 sampel, maka korelasi otomatisnya memiliki sampel 1999 (2 * N-1) yang bukan nol. Hanya 1000 sampel yang unik karena korelasi otomatis (untuk sinyal nyata) selalu simetris dalam waktu, yaitu ac [n] = ac [-n].

Sinyal kontinu perlu dipecah menjadi segmen terbatas. Itu mirip dengan Transformasi Fourier: secara teknis Anda perlu mengintegrasikan dari -inf ke + inf tetapi memecahnya menjadi segmen (dengan tumpang tindih dan / atau windowing sesuai kebutuhan) juga menghasilkan hasil yang bermanfaat. Pilihan panjang jendela, bentuk dan tumpang tindih tergantung pada aplikasi.

Hilmar
sumber