Kiat untuk meningkatkan deteksi nada

21

Saya sedang mengerjakan aplikasi web sederhana yang memungkinkan pengguna menyetel gitarnya. Saya seorang pemula yang nyata dalam pemrosesan sinyal, jadi jangan menilai terlalu keras jika pertanyaan saya tidak tepat.

Jadi, saya berhasil mendapatkan frekuensi dasar menggunakan algoritma FFT dan pada titik ini aplikasinya berfungsi. Namun, ada ruang untuk perbaikan, saat ini saya mengirim pcm mentah ke algoritma FFT, tetapi saya berpikir bahwa mungkin ada beberapa algoritma / filter pra / pasca yang dapat meningkatkan deteksi. Bisakah Anda menyarankan?

Masalah utama saya adalah ketika mendeteksi frekuensi tertentu itu menunjukkan frekuensi itu untuk 1-2sec dan kemudian melompat ke frekuensi acak lainnya dan kembali lagi dan seterusnya, bahkan jika suara terus menerus.

Saya juga tertarik pada jenis optimasi lainnya jika seseorang memiliki pengalaman dengan hal-hal seperti itu.

Valentin Radu
sumber

Jawaban:

20

Saya menduga frekuensi lain yang didapat adalah harmonik dari fundamental? Seperti Anda bermain 100 Hz dan memilih 200 Hz atau 300 Hz sebagai gantinya? Pertama, Anda harus membatasi ruang pencarian Anda pada frekuensi yang mungkin terjadi pada gitar. Temukan fundamental tertinggi yang mungkin Anda butuhkan dan batasi untuk itu.

Autokorelasi akan bekerja lebih baik daripada FFT dalam menemukan fundamental, jika fundamental lebih rendah dalam amplitudo daripada harmonik (atau hilang sama sekali, tetapi itu bukan masalah dengan gitar):

masukkan deskripsi gambar di sini

Anda juga dapat mencoba membobot frekuensi yang lebih rendah untuk menekankan yang mendasar dan meminimalkan harmonik, atau menggunakan algoritma pemetik puncak seperti ini dan kemudian hanya memilih frekuensi terendah.

Juga, Anda harus mengarahkan sinyal Anda sebelum menerapkan FFT. Anda hanya mengalikannya dengan fungsi jendela , yang mengurangi awal dan akhir bentuk gelombang untuk membuat spektrum frekuensi lebih bersih. Kemudian Anda mendapatkan paku sempit tinggi untuk komponen frekuensi, bukan yang luas.

Anda juga dapat menggunakan interpolasi untuk mendapatkan puncak yang lebih akurat. Ambil log spektrum, lalu paskan parabola ke puncak dan dua titik tetangga, dan temukan puncak sejati parabola. Anda mungkin tidak membutuhkan keakuratan sebanyak ini.

Berikut ini contoh kode Python saya untuk semua ini .

endolith
sumber
Inilah yang saya cari, jawaban yang sangat bagus, terima kasih!
Valentin Radu
2
Mengalikannya dengan fungsi jendela yang meruncing benar-benar akan menghapus semua garis spektral dalam sinyal Anda, sehingga membuatnya lebih luas. Namun, yang dapat Anda beli adalah rentang dinamis, yang memungkinkan Anda mengidentifikasi, misalnya, garis spektral berdaya rendah dengan adanya nada mengganggu daya tinggi.
Jason R
@JasonR mengingat fakta bahwa ini dirancang untuk bekerja di lingkungan di mana probabilitas nada mengganggu daya tinggi sangat rendah, apakah Anda menyarankan bahwa lebih baik tidak menggunakan jendela Hamming?
Valentin Radu
1
Saya dapat mengkonfirmasi bahwa menggunakan jendela Hamming membuat saya semakin dekat dengan tujuan saya untuk menjaga agar bacaan tetap stabil. Saat ini, ketika saya memainkan A4 saya mendapatkan 440 Hz sebagian besar waktu dan sangat jarang saya mendapatkan pembacaan dekat seperti 650 Hz atau lebih. Saya kira itu harmonik? Juga, saya tidak dapat membantu memperhatikan bahwa untuk frekuensi yang lebih tinggi aplikasi bekerja tanpa cacat dan untuk yang lebih rendah mulai gagal. Mungkin karena saya menggunakan FTT untuk mendeteksi bin frekuensi frekuensi puncak dan untuk frekuensi yang lebih rendah itu tidak selalu yang mendasar?
Valentin Radu
1
@mindnoise: 660 Hz bukan harmonik dari 440 Hz, tetapi harmonik dari 220 Hz, atau sempurna kelima di atas 440. Bisa jadi string lain beresonansi atau distorsi atau sesuatu? Jauh lebih mudah untuk mencari tahu masalah seperti ini jika Anda dapat merencanakan FFT dan melihatnya. Ya, frekuensi rendah mungkin disaring dan dikurangi relatif terhadap yang lebih tinggi, baik oleh efek mekanis atau oleh sirkuit analog Anda.
endolith
12

Lapangan tidak sama dengan nampan frekuensi magnitudo puncak dari FFT. Pitch adalah fenomena psiko-akustik manusia. Suara pitch dapat memiliki fundamental yang hilang atau sangat lemah (umum dalam beberapa suara, piano dan suara gitar) dan / atau banyak nada kuat dalam spektrumnya yang melebihi frekuensi nada (tetapi masih terdengar sebagai nada nada yang dicatat oleh manusia) . Jadi setiap detektor frekuensi puncak FFT (bahkan termasuk beberapa windowing dan interpolasi) tidak akan menjadi metode estimasi pitch yang kuat.

Pertanyaan stackoverflow ini mencakup daftar beberapa metode alternatif untuk memperkirakan pitch yang mungkin menghasilkan hasil yang lebih baik.

TAMBAH: Jika Anda melakukan ini untuk suara gitar, perhatikan bahwa senar gitar terendah sebenarnya dapat menghasilkan nada sedikit inharmonik, membuat estimasi nada lebih sulit, karena telinga manusia mungkin mendengar frekuensi nada yang lebih dekat terkait dengan sub-kelipatan nada , daripada frekuensi getaran fundamental aktual dari string.

TAMBAH # 2: Ini sering ditanyakan sehingga saya menulis posting blog yang lebih panjang pada topik: http://www.musingpaw.com/2012/04/musical-pitch-is-not-just-ff-fft-frequency.html

hotpaw2
sumber
baru saja mengunjungi (dan mengomentari) blog yang baru saja Anda referensikan kepada kami.
robert bristow-johnson
5

Saya menghabiskan bertahun-tahun meneliti pendeteksian nada pada musik polifonik - seperti mendeteksi nada-nada dari solo gitar dalam rekaman mp3. Saya juga menulis bagian di Wikipedia yang memberikan uraian singkat tentang prosesnya (lihat subbagian "Pendeteksian Pitch" di tautan di bawah).

Ketika satu tombol ditekan pada piano, apa yang kita dengar bukan hanya satu frekuensi getaran suara, tetapi gabungan dari beberapa getaran suara yang terjadi pada frekuensi yang berhubungan secara matematis berbeda. Unsur-unsur komposit getaran ini pada frekuensi yang berbeda disebut sebagai harmonik atau parsial. Misalnya, jika kita menekan tombol C Tengah pada piano, frekuensi individual harmonik komposit akan mulai pada 261,6 Hz sebagai frekuensi dasar, 523 Hz akan menjadi Harmonik ke-2, 785 Hz akan menjadi Harmonik ke-3, 1046 Hz akan menjadi Harmonika ke-4, dll. Harmonisa selanjutnya adalah kelipatan bilangan bulat dari frekuensi dasar, 261,6 Hz (mis: 2 x 261,6 = 523, 3 x 261,6 = 785, 4 x 261,6 = 1046).

Saya menggunakan DFT Logarithmic Transform yang dimodifikasi untuk pertama-tama mendeteksi kemungkinan harmonisa dengan mencari frekuensi dengan level puncak (lihat diagram di bawah). Karena cara saya mengumpulkan data untuk Log DFT saya yang dimodifikasi, saya TIDAK harus menerapkan Fungsi Windowing ke sinyal, juga tidak menambah dan tumpang tindih . Dan saya telah membuat DFT sehingga saluran frekuensinya terletak secara logaritma untuk menyelaraskan langsung dengan frekuensi di mana harmonik dibuat oleh not pada gitar, saksofon, dll.

Sekarang sedang pensiun, saya telah memutuskan untuk merilis kode sumber untuk mesin deteksi pitch saya dalam aplikasi demonstrasi gratis yang disebut PitchScope Player . PitchScope Player tersedia di web, dan Anda bisa mengunduh executable untuk Windows untuk melihat algoritme saya bekerja pada file mp3 yang Anda pilih. Tautan di bawah ini ke GitHub.com akan mengarahkan Anda ke kode sumber lengkap saya di mana Anda dapat melihat bagaimana saya mendeteksi harmonik dengan transformasi DFT Logarithmic kustom, dan kemudian mencari parsial (harmonik) yang frekuensinya memenuhi hubungan bilangan bulat yang benar yang mendefinisikan ' nada'.

Algoritma Deteksi Pitch Saya sebenarnya adalah proses dua tahap: a) Pertama ScalePitch terdeteksi ('ScalePitch' memiliki 12 nilai nada yang mungkin: {E, F, F #, G, G #, A, A #, B, C, C #, D , D #}) b) dan setelah ScalePitch ditentukan, maka Oktaf dihitung dengan memeriksa semua harmonik untuk 4 kemungkinan catatan Oktaf-Calon. Algoritma ini dirancang untuk mendeteksi nada paling dominan (not musik) pada waktu tertentu dalam file MP3 polifonik. Itu biasanya sesuai dengan catatan solo instrumental. Mereka yang tertarik dengan kode sumber C ++ untuk algoritma 2 Stage Pitch Detection saya mungkin ingin memulai pada fungsi Estimate_ScalePitch () dalam file SPitchCalc.cpp di GitHub.com.

https://github.com/CreativeDetectors/PitchScope_Player

https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection

Di bawah ini adalah gambar DFT Logaritmik (dibuat oleh perangkat lunak C ++ saya) selama 3 detik dari solo gitar pada rekaman mp3 polifonik. Ini menunjukkan bagaimana harmonik muncul untuk not individu pada gitar, saat bermain solo. Untuk setiap catatan pada DFT Logaritmik ini kita dapat melihat beberapa harmoniknya memanjang secara vertikal, karena masing-masing harmonik memiliki lebar waktu yang sama. Setelah oktaf nota ditentukan, maka kita mengetahui frekuensi Fundamental.

masukkan deskripsi gambar di sini

Diagram di bawah ini menunjukkan algoritme Deteksi Oktaf yang saya kembangkan untuk memilih nada Oktaf-Calon yang benar (yaitu, Fundamental yang benar), setelah ScalePitch untuk catatan tersebut telah ditentukan. Mereka yang ingin melihat metode dalam C ++ harus pergi ke fungsi Calc_Best_Octave_Candidate () di dalam file yang disebut FundCandidCalcer.cpp, yang terkandung dalam kode sumber saya di GitHub.

masukkan deskripsi gambar di sini

James Paul Millard
sumber
James, apakah detektor pitch DFT Anda mendeteksi nada dengan fundamental yang hilang (atau lemah)?
robert bristow-johnson
Ya, algoritme Deteksi Pitch 2 Tahap saya akan mendeteksi catatan, meskipun sinyal memiliki fundamental "hilang (atau lemah)" - itu adalah kekuatan besar dari proses 2 tahap ini. Fundamental ditentukan pada tahap kedua ketika Deteksi Oktaf dilakukan pada lebar waktu yang Anda lihat untuk catatan pada diagram DFT Logaritmik. Karena fungsi Deteksi Pitch ini berfungsi dalam kebingungan sinyal mp3 polifonik, ia akan mendeteksi catatan yang kehilangan banyak harmonisa, termasuk Fundamental. Saya baru saja menambahkan ke Jawaban ini diagram kedua yang menjelaskan algoritme Deteksi Oktaf saya.
James Paul Millard