Ses analizinde otokorelasyon


11

Otokorelasyon hakkında okuyorum , ama tam olarak nasıl çalıştığını ve hangi çıktıyı beklemem gerektiğini anladığımdan emin değilim. Sinyalimi AC fonksiyonuna girmem ve kayan bir pencere girişine sahip olmam gerektiğini düşünüyor muyum? Her pencere (örneğin 1024 örnekten) -1 ile 1 arasında bir katsayı üretir. İşaret basitçe çizginin yukarı veya aşağı olup olmadığını belirtir ve değer korelasyonun ne kadar güçlü olduğunu belirtir. Basitlik için, bir çakışma yok ve sadece pencereyi her seferinde 1024 örnek taşıdığımı varsayalım. 44100'lük bir örnekte 43 katsayı alır mıyım ve hepsini tutmam gerekir mi?

Diyelim ki 200 saniyelik bir sinyal için bunu 8600 katsayı veriyorum. Bu katsayıları tekrar ve sırayla tempoyu tespit etmek için nasıl kullanırım? Onları gruplandırmak için bir çeşit sinir ağı oluşturmalı mıyım yoksa bu aşırı mı?

Herhangi bir yardım için teşekkürler.


4
örneğinizin olduğunu varsayalım . AC fonksiyonunuzun ne getirdiğini söyleyebilir misiniz? Olası cevaplar olabilir: "Bu döner " ya da "Bu döner numaraları burada "ya da" Bu döner numaraları burada ". Önerilen üç cevap da otokorelasyon kavramıyla uyumludur. 1024x[1],x[2],...,x[1024]Σben=11024(x[ben])21024R,[k]R,[k]=Σben=11024-kx[ben]x[ben+k]1024R,[k]R,[k]=Σben=11024-kx[ben]x[ben+k]+Σben=1kx[1024-k+ben]x[ben]
Dilip Sarwate

Hey Dilip, yardımın için teşekkürler. Henüz AC fonksiyonunu uygulamadım, sadece önce kafamı teoriye sokmaya çalışıyorum. İlk denklem en kolay gibi görünüyor, ancak verilerin önceden normalleştirilmesi gerekiyor mu?
XSL

1
İşte bir örnek: gist.github.com/255291#L62
Endolit

Yanıtlar:


23

Otokorelasyon fikri, belirli bir gecikmede bir sinyal ile kendisi arasındaki benzerlik ölçüsünü sağlamaktır. Yaklaşmanın birkaç yolu vardır, ancak perde / tempo algılaması amacıyla, bunu bir arama prosedürü olarak düşünebilirsiniz. Başka bir deyişle, örnek örnek sinyalinde ilerlersiniz ve referans pencereniz ile gecikmeli pencere arasında bir korelasyon gerçekleştirirsiniz. "Lag 0" daki korelasyon global maksimum olacaktır, çünkü referansı kendisinin birebir kopyasıyla karşılaştırıyorsunuz. İlerledikçe, korelasyon mutlaka azalır, ancak periyodik bir sinyal durumunda, bir noktada tekrar artmaya başlar, ardından yerel bir maksimuma ulaşır. "Gecikme 0" ile ilk zirve arasındaki mesafe, adım / temponuz hakkında bir tahmin verir. Benim yolum

Numune-örnek korelasyonlarının hesaplanması, yüksek numune oranlarında çok hesaplamalı olarak pahalı olabilir, bu nedenle tipik olarak FFT tabanlı bir yaklaşım kullanılır. İlgili segmentin FFT'sini almak, karmaşık konjugatı ile çarpmak , sonra ters FFT'yi almak size döngüsel otokorelasyon verecektir . Kodda ( numpy kullanarak ):

freqs = numpy.fft.rfft(signal)
autocorr = numpy.fft.irfft(freqs * numpy.conj(freqs))

Etki, sinyaldeki (kendisiyle ilintisiz) gürültü miktarını periyodik bileşenlere (tanım gereği kendilerine benzer) göre azaltmak olacaktır. Ters dönüşümü almadan önce otokorelasyonun (yani eşlenik çarpma) tekrarlanması gürültüyü daha da azaltacaktır. Beyaz gürültüyle karıştırılmış bir sinüs dalgası örneğini düşünün. Aşağıdaki grafik 440hz sinüs dalgasını, aynı sinüs dalgasının gürültü ile "bozulduğunu", gürültülü dalganın döngüsel otokorelasyonunu ve çift döngüsel otokorelasyonunu göstermektedir:

otokorelasyon

Her iki otokorelasyon sinyalinin ilk zirvesinin tam olarak orijinal sinyalin ilk çevriminin sonunda bulunduğuna dikkat edin. Periyodikliği belirlemek için aradığınız zirve budur (bu durumda adım). İlk otokorelasyon sinyali hala biraz "wiggly" dir, bu nedenle pik tespiti yapmak için bir tür düzleştirme gerekecektir. Frekans alanında iki kez otokorelasyon aynı şeyi başarır (ve nispeten hızlıdır). "Kıpır kıpır" ile sinyalin yakınlaştırıldığında nasıl göründüğünü kastediyorum, arsa merkezinde meydana gelen eğimi değil. Döngüsel otokorelasyonun ikinci yarısı her zaman ilk yarının ayna görüntüsü olacaktır, böylece bu tür bir "daldırma" tipiktir. Sadece algoritma hakkında net olmak için, kodun nasıl görüneceği aşağıda açıklanmıştır:

freqs = numpy.fft.rfft(signal)
auto1 = freqs * numpy.conj(freqs)
auto2 = auto1 * numpy.conj(auto1)
result = numpy.fft.irfft(auto2)

Birden fazla otokorelasyon yapmanız gerekip gerekmediği, sinyalde ne kadar gürültü olduğuna bağlıdır.

Tabii ki, bu fikir üzerinde birçok ince varyasyon var ve bunların hepsine burada girmeyeceğim. Gördüğüm en kapsamlı kapsam (perde algılama bağlamında) Rabiner ve Schafer tarafından yapılan Konuşma Sinyallerinin Dijital İşlenmesi .


Şimdi, otokorelasyonun tempo algılaması için yeterli olup olmayacağı. Cevap evet ve hayır. Bazı tempo bilgilerini (kaynak sinyaline bağlı olarak) alabilirsiniz, ancak her durumda bunun ne anlama geldiğini anlamak zor olabilir. Örneğin, burada bir breakbeat'ın iki döngüsünün bir grafiği ve ardından tüm dizinin döngüsel otokorelasyonunun bir grafiği:

Breakbeat Otokorelasyonu

Referans için, ilgili ses şöyledir:

Elbette, ortada döngü noktasına karşılık gelen güzel bir artış var, ancak oldukça uzun bir segmentin işlenmesinden geldi. Bunun da ötesinde, eğer tam bir kopya olmasaydı (örneğin onunla enstrümantasyon varsa), bu artış o kadar temiz olmazdı. Otokorelasyon, tempo algılamasında kesinlikle yararlı olacaktır, ancak muhtemelen karmaşık kaynak malzemeler için kendi başına yeterli olmayacaktır. Örneğin, bir artış bulsanız bile, bunun tam bir ölçü mü, çeyrek nota mı, yarım nota mı yoksa başka bir şey olduğunu nasıl anlarsınız? Bu durumda, bunun tam bir önlem olduğu yeterince açıktır, ancak bu her zaman böyle olmayacaktır. İç çalışmalar netleşene kadar daha basit sinyallerde AC ile oynamayı, sonra genel olarak tempo algılama hakkında başka bir soru sormayı öneririm (çünkü "daha büyük"


2
Bekle, ses sinyalinin kendisinin otokorelasyonu mu? Bu, dijital döngülerden başka bir şeyin tempo tespiti için kesinlikle çok yararlı değildir. Bazı RMS zarflarının otokorelasyonu, tercihen birden fazla frekans bandı için ayrı ayrı genel olarak çok daha iyi çalışmalıdır.
leftaroundabout

1
STFT'nin zaman yönünde otokorelasyonu, müziğin bir tür ritmi olduğu sürece oldukça iyi çalışıyor . Bu aslında birçok frekans bandının otokorelasyonunu çalıştırmak ve sonra bunları toplamakla aynıdır.
Endolit

2
@leftroundabout Doğru, kendi başına otokorelasyonun yanı sıra tempo tespiti için (işlem öncesi, işlem sonrası) yapılması gereken çok sayıda şey var. Ben esas olarak OP sorusunun ilk cümlesine (yani "otokorelasyon nasıl çalışır") yanıt veriyorum, daha sonra tempo tespiti hakkında başka bir soru sormayı önerdi, çünkü diğer süreçler dahil olacak.
datageist

@endolith Burada ne demek istiyorsun Autocorrelation of the STFT in the time direction? Özellikle zaman yönü bölümü
popctrl 11:19

1
@popctrl STFT her sıranın otokorelasyon hesaplamak Anlamı
Endolit

3

Vuruş tespiti yapmak için otokorelasyon kullanmak istediğiniz gibi geliyor. Bunu yapabilirsin, ama sesini büyük ölçüde küçültmeni öneririm. 1 ve 3 Hz (60 bpm - 180 bpm) arasında bir sinyal arıyorsunuz, böylece 44100 hz çözünürlüğe ihtiyacınız yoktur veya istemezsiniz. Düzgün bir şekilde hesaplanmış ve normalleştirilmiş bir otokorelasyon gecikme 0'da 1.0'dır (sinyal kendisiyle mükemmel bir şekilde ilişkilidir). Periyodik bir sinyal için, ac sıfırın altına düşer, daha sonra temel frekansa karşılık gelen gecikmede bir tepe noktasına geri döner ve harmoniklerde daha küçük pikler gelir. Bu zirveyi aramak için makul bir aralık seçmelisiniz. Gürültü için, otokorelasyon düşer ve temelde sıfıra yakın dalgalı çizgilerle düz çizgiler oluşturur. Genel bir kural olarak, normalleştirilmiş AC'de> 0,5 değerinde bir tepe noktasına sahipseniz, periyodik bir sinyaliniz olur.


1

Otomatik korelasyon basitçe bir sinyalin kendisiyle çapraz korelasyonudur. Bunu hesaplamanın kolay bir yolu, orijinal sinyal ile sinyalin zaman çevrimli bir versiyonu arasında bir kıvrım yapmaktır. 1000 örnek uzunluğunda bir sinyaliniz varsa, otomatik korelasyonundan 1999 (2 * N-1) sıfır olmayan örnek vardır. Bu örneklerin sadece 1000'i benzersizdir çünkü otomatik korelasyon (gerçek bir sinyal için) her zaman zaman içinde simetriktir, yani ac [n] = ac [-n].

Sürekli sinyallerin sonlu bölümlere ayrılması gerekir. Fourier Dönüşümü'ne benzer: teknik olarak -inf'den + inf'ye entegre etmeniz gerekir, ancak onu parçalara ayırın (gerektiğinde üst üste binme ve / veya pencereleme ile) de yararlı sonuçlar verir. Pencere uzunluğu, şekli ve üst üste binme seçimi uygulamaya bağlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.