Bisakah saya menggunakan FFT untuk mengenali not musik pada piano?

13

Saya ingin membuat alat yang mengenali beberapa not musik (saya tahu ini menciptakan kembali roda). Jadi saya akan memainkan C tengah, D, dan E pada piano dan itu harus dapat mengklasifikasikan catatan tersebut. Inilah cara saya pikir saya harus mendekatinya:

  1. Rekam sampel saya yang memainkan not
  2. Konversikan sinyal ke domain frekuensi menggunakan transformasi fourier cepat
  3. Temukan frekuensi yang paling banyak muncul (pada dasarnya argmax dari data domain frekuensi)
  4. Asumsikan frekuensi berasal dari not yang dimainkan dan gunakan itu untuk mengklasifikasikan not tersebut

Saya belum mencoba semua ini karena saya tidak ingin memulai jalan yang salah. Jadi, secara teori, apakah ini akan berhasil?

michaelsnowden
sumber
Alangkah baiknya jika Anda bisa lebih spesifik dalam judul. Saya mencoba memasukkan sedikit tentang pengenalan nada piano, tetapi bahasa Inggris saya (non-pribumi) ternyata mengecewakan saya hari ini.
pipa
1
@pipe ok saya mengubahnya
michaelsnowden
1
"Sampel" Anda memainkan not seharusnya sudah menjadi bentuk gelombang amplitudo dan waktu. Pada dasarnya, poin 2 berlebihan. Untuk implementasi yang relatif sederhana, langkah-langkah Anda di atas seharusnya baik-baik saja.
user2943160
@ user2943160 Saya menambahkannya secara eksplisit. Suara dapat disimpan dalam banyak format, dan biasanya butuh beberapa pengaturan untuk membuatnya menjadi amplitudo yang bagus seiring waktu.
michaelsnowden
@michaelsnowden: Anda menggunakan istilah "amplitudo" salah: amplitudo fungsi sinusoidal adalah A . Ini adalah maksimum sinyal (tegangan, perpindahan, ...) dan ini adalah konstan (atau perlahan-lahan berubah sehubungan dengan frekuensi). Yang Anda maksud hanyalah sinyal y ( t ) . Kalau tidak, saya akan berpikir dengan "amplitudo dari waktu ke waktu" maksud Anda amplop sinyal tetapi sejauh yang saya mengerti Anda tidak. y(t)=SEBUAHdosa(ωt)SEBUAHy(t)
Curd

Jawaban:

23

Konsepnya bagus, tetapi dalam praktiknya tidak sesederhana itu.

Pitch bukan hanya nada dominan, jadi ada masalah nomor 1.

Tempat frekuensi FFT tidak dapat menekan semua (atau bahkan beberapa) nada skala musik secara bersamaan.

Saya menyarankan bermain dengan program audio (misalnya, Audacity) yang mencakup penganalisis FFT dan penghasil nada untuk merasakan apa yang dapat dilakukan (dan tidak bisa) dilakukan sebelum Anda mencoba menerapkan tugas tertentu menggunakan FFT.

Jika Anda perlu mendeteksi hanya beberapa nada tertentu, Anda mungkin menemukan algoritma Goertzel lebih mudah dan lebih cepat.

Deteksi pitch rumit, dan masih ada penelitian di bidang itu. Deteksi nada cukup mudah, tetapi mungkin tidak memberikan apa yang Anda inginkan.

JRE
sumber
Jika kita mulai dengan asumsi bahwa sampel adalah instrumen tertentu, masalahnya mungkin sedikit lebih mudah untuk ditangani, bukan?
Nyonya
Ini terlihat sangat bagus. Satu pertanyaan tindak lanjut adalah: dapatkah Algoritma Goertzel digunakan untuk mendeteksi dua not yang sedang dimainkan secara bersamaan?
michaelsnowden
Ini dapat digunakan untuk mendeteksi nada simultan. Apakah itu cukup untuk mendeteksi catatan simultan adalah pertanyaan yang berbeda, dan saya masih mengerjakannya. Saya memiliki detektor catatan gitar berbasis Goertzel yang telah saya pakai selama bertahun-tahun.
JRE
2
@keith: Semacam. Anda dapat menguji catatan dan melihat apakah mendeteksi nada dominan cukup untuk instrumen tertentu (dan mungkin hanya nada yang menarik.) Sejauh yang saya tahu, tidak ada solusi umum untuk mendeteksi semua nada dari semua instrumen.
JRE
3

Saya akan mengatakan menggunakan jendela observasi multimodal dari sinyal akan lebih baik. Sesuatu di sepanjang garis dekomposisi wavelet sinyal audio Anda yang akan memungkinkan Anda untuk mengidentifikasi beberapa nada di dalam catatan. Yup, sebenarnya Wavelet, saya akan katakan adalah cara untuk pergi.

Ini adalah rincian yang sangat umum dari apa wavelet itu, tetapi menganggap mereka sebagai jendela multiresolusi yang melewati sinyal Anda seperti STFT. Jadi Anda dapat mengidentifikasi berbagai sinusoidals yang terjadi di lokasi temporal yang berbeda dalam sinyal Anda. ini juga penting karena not yang Anda mainkan bukanlah sinyal stasioner, not yang diputar kemudian meluruh seiring waktu. Saya bukan seorang musisi, namun saya percaya bahwa dominasi nada berubah sepanjang peluruhan not.

tentu saja setelah dekomposisi wavelet, Anda perlu mengimplementasikan algoritma yang mengidentifikasi nada dan nada periferal.

Saya pikir wavelet benar-benar mengatasi masalah yang orang telah talkaning dalam hal identifikasi pitch.

jika Anda ingin mempelajari cara kerja wavelet, ini adalah whitepaper luar biasa yang dikeluarkan oleh HP tentang hal itu :) http://www.hpl.hp.com/hpjournal/94dec/dec94a6.pdf dan Pengantar Wavelet

untuk implementasi, MATLAB memiliki alat wavelet dan saya yakin ada banyak paket lain yang tersedia untuk platform seperti R, dll.

steve_stackex
sumber
1

Saya kira Anda memikirkan not yang dimainkan di tengah rentang piano (katakanlah antara 200 dan 500 Hz) tetapi bahkan dalam rentang piano itu, satu nada akan memiliki banyak nada, yang bukan kelipatan tepat dari frekuensi dasar, dan juga sejumlah besar kebisingan broadband di awal setiap catatan, dan mungkin juga di akhir.

Untuk not yang keras di ujung bawah kisaran not, Anda akan menemukan bahwa sangat sedikit energi suara (kurang dari 1%) yang sebenarnya ada di nada dasar nada.

Masalah lain adalah bahwa interpretasi naif dari FFT mengasumsikan sinyal yang Anda coba deteksi memiliki amplitudo konstan. Itu tidak berlaku untuk not piano di mana amplitudo benar-benar mengikuti beberapa peluruhan eksponensial yang dilapiskan - bagian awal peluruhan memiliki konstanta waktu yang relatif singkat, tetapi bagian selanjutnya memiliki konstanta waktu yang lebih lama.

Anda mungkin lebih baik menyelidiki metode transformasi Fourier skala pendek, misalnya transformasi Gabor, atau metode berbasis wavelet.

Perhatikan bahwa karena nada dasar nada beruntun meningkat sekitar 6% untuk setiap nada, Anda tidak perlu membutuhkan akurasi yang sangat tinggi dalam mengidentifikasi frekuensi harmonik dalam audio. Mengidentifikasi not-not musik dengan benar bukanlah masalah yang sama dengan menentukan apakah not-not tersebut secara akurat selaras dengan skala musik, di mana frekuensi mungkin perlu diukur untuk akurasi lebih dari 0,1%.

alephzero
sumber
0

Ya, inilah tujuan FFT! Untuk memberi Anda spektrum frekuensi dari data yang Anda makan. Bagian yang sulit adalah detail implementasi, seperti yang telah Anda sebutkan.

Bergantung pada apa yang ingin Anda lakukan, tepatnya, mengubah jawabannya.

Jika Anda hanya ingin menganalisis musik Anda sendiri, sudah ada perangkat lunak di luar sana untuk melakukan itu. Anda bisa melihat EQ yang menunjukkan respons (pada dasarnya FFT), atau mendapatkan "EQ musikal" yang menunjukkan nada juga. Anda bisa mendapatkan audio ke midi VST yang mengubah apa yang Anda mainkan menjadi catatan midi yang benar. Jika keyboard Anda adalah midi, lewati saja VST, dan rekam midi secara langsung.

Jika Anda ingin mengajari FFT sendiri dan hubungannya dengan musik, lebih baik dapatkan sesuatu seperti Matlab di mana Anda dapat menghitung FFT dari data apa pun. Ini memiliki kemampuan untuk merekam dan juga pemutaran bersama dengan membaca file wav dan semacamnya. Ini kemudian menjadi benar-benar mudah digunakan. Anda dapat membuat grafik audio dan melakukan semua jenis analisis dengan lebih cepat jika Anda tahu sintaksnya.

Jika Anda ingin membangun perangkat untuk melakukan hal seperti itu maka itu cukup rumit. Anda memerlukan uC / dsp / fpga / etc untuk melakukan perhitungan. Sebagian besar perangkat populer sudah dilengkapi dengan kode FFT sehingga Anda tidak perlu membuat kode sendiri (juga rumit).

Anda harus membangun sirkuit dan semua itu. Ini tidak sulit tetapi tergantung pada pengalaman / pengetahuan Anda, itu bisa memakan waktu dan memiliki kurva belajar yang curam. Itu juga tergantung pada kualitas produk akhir.

Secara matematis, not musik ideal terdiri dari deret geometris "fundamental".

Misalkan F0 adalah frekuensi dasar, maka sebagian besar not musik akan didekati oleh F (t) + F0 * jumlah (a_k e ^ (2 ^ k F0 * pi i t)) = F0 + a_1 * F1 + a_2 * F2 +. ...

A_k hanyalah kekuatan dari frekuensi yang lebih tinggi F_k dan F_k hanyalah beberapa kelipatan dari F0. Jika a_k = 0 untuk semua k, maka kita memiliki sinusoid murni. Pitch ini mudah dideteksi. Temukan saja maksimum FFT dan frekuensi itu adalah dasar dari nada = not musik.

Ketika Anda mengambil FFT, Anda berakhir dengan data itu, dan berhitung saja. Ini pada dasarnya kalkulus.

Semua itu relatif mudah.

Beberapa masalah yang harus Anda atasi. Perhatikan bahwa tidak semua ini "diselesaikan".

  1. Latensi - Jika Anda akan melakukan segala jenis hal waktu nyata, ini bisa menjadi masalah.

  2. Beberapa catatan - Sulit untuk menentukan kelompok catatan karena semua harmonik tambahan. Jika memainkan A = 440hz dan A '= 880hz, sebagian besar harmonik akan tumpang tindih. Anda dapat dengan mudah mendapatkan A = 440hz, tetapi mendapatkan A '= 880hz lebih sulit. Ketika Anda memikirkan akor, lari cepat, dll, maka bisa sangat sulit untuk mendapatkan semua informasi (catatan) dengan tepat. Meskipun secara umum semuanya secara matematis dimungkinkan, data itu sendiri memiliki kesalahan dan penyimpangan, dan persamaannya didefinisikan dalam beberapa kasus.

  3. Noise - Noise pada sinyal dapat memberi Anda hasil palsu. Jika kebisingan musik terjadi itu dapat mengacaukan hasil Anda. Algoritma yang lebih baik akan dibutuhkan = waktu + uang + pengetahuan.

Abstrak
sumber