Bagaimana ukuran jendela, laju sampel memengaruhi estimasi pitch FFT?

8

Saya mencoba membuat program deteksi pitch yang mengekstraksi frekuensi puncak dalam spektrum daya yang diperoleh dari FFT ( fftpack). Saya mengekstraksi frekuensi puncak dari spektrum saya menggunakan Penaksir Pertama Quinn untuk menginterpolasi antara nomor bin. Skema ini tampaknya bekerja dengan baik dalam kondisi tertentu. Misalnya, menggunakan fungsi jendela persegi panjang dengan ukuran jendela 1024 dan laju sampel 16000, algoritma saya dengan benar mengidentifikasi frekuensi nada A440 murnisebagai 440,06 dengan frekuensi parsial kedua 880,1. Namun, dalam kondisi lain, itu menghasilkan hasil yang tidak akurat. Jika saya mengubah laju sampel (misalnya menjadi 8000) atau ukuran jendela (misalnya menjadi 2048), ia masih mengidentifikasi dengan benar parsial pertama sebagai 440, tetapi parsial kedua ada di sekitar 892. Masalahnya menjadi lebih buruk untuk nada inharmonik seperti yang diproduksi oleh gitar atau piano.

Pertanyaan umum saya adalah: Dengan cara apa laju sampel, ukuran jendela, dan fungsi jendela memengaruhi estimasi frekuensi puncak FFT? Asumsi saya adalah bahwa hanya meningkatkan resolusi spektrum akan meningkatkan akurasi estimasi frekuensi puncak, tetapi ini jelas bukan pengalaman saya (zero padding juga tidak membantu). Saya juga berasumsi bahwa pilihan fungsi jendela tidak akan banyak berpengaruh karena kebocoran spektral seharusnya tidak mengubah lokasi puncak (meskipun, sekarang saya berpikir tentang hal itu, kebocoran spektral berpotensi mempengaruhi perkiraan frekuensi yang diinterpolasi jika besarnya tempat sampah yang berdekatan dengan puncak secara artifisial ditingkatkan oleh kebocoran dari puncak lainnya ...).

Adakah pikiran?

willpett
sumber

Jawaban:

8
  1. Gunakan jendela Gaussian - transformasi Fourier dari Gaussian adalah Gaussian
  2. Log skala skala untuk menekankan puncak dan mengubah puncak Gaussian menjadi puncak parabola
  3. Gunakan interpolasi parabola untuk menemukan puncak yang sebenarnya.

Perhatikan bahwa, sebagaimana disebutkan dalam §D.1, besarnya transformasi jendela Gaussian adalah parabola pada skala dB. Akibatnya, interpolasi puncak spektral kuadrat tepat di bawah jendela Gaussian. Tentu saja, kita harus entah bagaimana menghapus ekor Gaussian yang sangat panjang dalam praktiknya, tetapi ini tidak menyebabkan banyak penyimpangan dari parabola, seperti yang ditunjukkan pada Gambar 3.30.

https://ccrma.stanford.edu/~jos/sasp/Quadratic_Interpolation_Spectral_Peaks.html

masukkan deskripsi gambar di sini

Saya perkirakan 1000.000004 Hz untuk bentuk gelombang 1000 Hz dengan cara ini: https://gist.github.com/255291#file_parabolic.py

Jika Anda mengalami masalah, plot spektrum dan gunakan mata Anda untuk melihat mengapa itu tidak berfungsi.

endolit
sumber
2
Terima kasih! Ini masuk akal. Log Gaussian adalah parabola, jadi interpolasi parabola dari puncak dalam spektrum log window Gaussian hampir tepat. Setelah menerapkan ini, saya mendapatkan estimasi frekuensi puncak FFT yang konsisten di berbagai tingkat sampel dan ukuran jendela. Sabas!
willpett
@ will.pett: Jadi mungkin masalahnya disebabkan oleh "Pengukur Pertama Quinn" lebih dari oleh FFT?
endolith
Saya tidak berpikir metode interpolasi sepenuhnya untuk disalahkan karena interpolasi kuadrat juga memberi saya hasil yang buruk dengan fungsi jendela tertentu dan tingkat sampel. Saya pikir itu adalah kombinasi dari parameter di atas yang penting. Saya tidak menggunakan fungsi jendela yang tepat dan belum log-transformasi spektrum saya. Saya yakin yang paling penting adalah log-transform. Mungkin protokol standar yang tidak saya sadari.
willpett
@endolith, terima kasih, mengerti (pertanyaan dapat menyusul)
denis
3

Pertama, estimasi frekuensi puncak dan estimasi pitch adalah dua hal yang berbeda. Pitch adalah fenomena psiko-akustik. Orang dapat mendengar nada bahkan dengan frekuensi dasar benar-benar hilang, atau relatif lemah dibandingkan dengan kebanyakan puncak lainnya, seperti pada nada rendah yang dihasilkan oleh beberapa instrumen.

Kedua, tidak menggunakan jendela pada FFT sama dengan menggunakan jendela persegi panjang, yang menggabungkan spektrum Anda dengan fungsi Sinc. Fungsi Sinc memiliki banyak punuk yang tersebar jauh dari puncak yang akan muncul untuk semua frekuensi yang tidak persis periodik dalam panjang FFT (juga dikenal sebagai "kebocoran spektral"). Semua kebocoran energi ini dari satu frekuensi yang kuat akan mengganggu estimasi posisi puncak frekuensi lainnya. Jadi fungsi jendela yang lebih cocok (Hamming atau von Hann) dapat membantu mengurangi gangguan antar puncak.

FFT yang lebih lama akan mengurangi frekuensi delta antara pusat-pusat bin, yang harus meningkatkan interpolasi dan dengan demikian akurasi estimasi frekuensi untuk spektrum stasioner. Namun jika FFT terlalu panjang sehingga spektrum berubah di dalam jendela FFT, semua frekuensi yang diubah itu akan dikaburkan dalam FFT yang lebih panjang.

hotpaw2
sumber
1

Anda pasti memerlukan fungsi jendela yang sesuai - efek kebocoran spektral sangat bervariasi tergantung pada bagaimana periode pitch dan panjang jendela FFT terkait - jika Anda mendapatkan transien besar antara sampel terakhir dan pertama dari jendela FFT maka ini akan menghasilkan sangat buruk mengolesi spektrum, sedangkan jika Anda beruntung dan diskontinuitas ini kecil maka spektrum yang dihasilkan akan jauh lebih bersih. Ini mungkin mengapa Anda melihat inkonsistensi ketika Anda mengubah salah satu parameter Anda seperti ukuran FFT. Dengan fungsi jendela yang sesuai, Anda akan mendapatkan spektrum yang konsisten saat nada berubah.

Paul R
sumber
Saya sekarang telah mencoba berbagai fungsi jendela (Hamming, Blackman-Harris, Gauss, Weedon-Gauss) dan semuanya memberi saya hasil yang sangat tidak akurat di bawah setiap laju sampel / kondisi ukuran jendela (misalnya memperkirakan frekuensi parsial pertama pada 460, 488, dan lainnya). Hanya jendela persegi panjang yang dapat mengidentifikasi dengan benar puncak pada 440 Hz. Menariknya, puncak ini sebagian besar invarian dengan berbagai sampel-laju / kombinasi ukuran jendela di jendela persegi panjang, meskipun parsial kedua masih variabel. Bagaimana saya merekonsiliasi hasil ini dengan saran Anda?
Sebagai catatan, saya juga menggunakan algoritma autokorelasi untuk membandingkan dengan FFT. Metode ini (yang tidak tergantung pada fungsi jendela) memberikan ~ 440,4 Hz untuk nada wikipedia, sedangkan metode FFT menghasilkan hampir 440 persis tanpa fungsi jendela. Saya menyadari bahwa autokorelasi tidak secara langsung memperkirakan frekuensi parsial pertama, tetapi lebih pada "nada" psikoacoustic, tetapi masih menarik untuk dibandingkan. Dari bereksperimen dengan nada piano, saya perhatikan bahwa metode autokorelasi secara konsisten melebih-lebihkan frekuensi parsial pertama dibandingkan dengan metode FFT.
1
Sulit untuk menebak apa masalahnya tanpa melihat kode dll. Pernahkah Anda mencoba merencanakan spektrum daya untuk melihat seperti apa puncak sebenarnya dengan / tanpa fungsi jendela? Ini seharusnya tidak hanya memberi tahu Anda apakah windowing / FFT / etc Anda berperilaku dengan benar tetapi juga dapat memberi Anda beberapa wawasan tentang mengapa estimasi pitch Anda juga memberikan hasil yang dilakukannya.
Paul R
Ini aneh, karena fungsi jendela memang menghasilkan spektrum tampak lebih bersih, dengan sedikit corengan. Namun, perkiraan frekuensi puncak tidak tepat. Ketika saya menggunakan pengaturan yang memberi saya 440 Hz tanpa jendela, kemudian beralih ke jendela Hamming, saya mendapatkan 444,6 Hz. Dengan jendela Blackman-Harris saya mendapatkan 460,9 Hz, dan dengan jendela Gaussian saya mendapatkan 446,4 Hz. Apakah mungkin bahwa metode interpolasi puncak membuat asumsi implisit tentang fungsi jendela yang mungkin saya langgar?
willpett
Saya tidak terlalu akrab dengan metode interpolasi dalam artikel yang Anda tautkan - mereka tampaknya menggunakan informasi magnitude dan fase daripada hanya magnitude, tetapi saya tidak akan berpikir bahwa windowing akan berdampak signifikan pada fase.
Paul R