Isi kandungan:

Pengesan Nota Muzik Arduino: 3 Langkah
Pengesan Nota Muzik Arduino: 3 Langkah

Video: Pengesan Nota Muzik Arduino: 3 Langkah

Video: Pengesan Nota Muzik Arduino: 3 Langkah
Video: Amazing arduino project 2024, Disember
Anonim
Image
Image

Mengesan nota muzik dari isyarat audio sukar dilakukan terutamanya di Arduino kerana daya ingatan dan pemprosesan yang terhad. Secara amnya, nota itu bukan gelombang sinus murni yang menyukarkan pengesanan. Sekiranya kita melakukan transformasi frekuensi dari pelbagai alat muzik, ia mungkin mengandungi pelbagai harmonik berdasarkan nota yang dimainkan. Setiap instrumen mempunyai kombinasi khas dari pelbagai harmonik. Dalam kod ini, saya cuba membuat program yang dapat merangkumi sebanyak mungkin instrumen. Anda boleh merujuk video yang dilampirkan di mana saya cuba menguji pelbagai jenis instrumen, pelbagai jenis nada yang dihasilkan oleh papan kekunci, dan bahkan suara vokal diperiksa. Ketepatan pengesanan berbeza dari instrumen ke instrumen. Untuk beberapa instrumen (iaitu piano) dalam jarak terhad (200-500Hz), ia tepat, sementara beberapa instrumen mempunyai ketepatan rendah (iaitu Harmonica).

Kod ini menggunakan kod FFT yang dikembangkan sebelumnya yang disebut EasyFFT.

Demonstrasi kod ditunjukkan dalam video di atas dengan pelbagai jenis bunyi instrumen dan juga vokal.

Bekalan

- Arduino Nano / Uno atau ke atas

- Modul mikrofon untuk Arduino

Langkah 1: Algoritma untuk Pengesanan Catatan

Seperti disebutkan pada langkah sebelumnya, pengesanannya sulit karena adanya banyak frekuensi dalam sampel audio.

Program ini berfungsi dalam aliran berikut:

1. Perolehan data:

- bahagian ini mengambil 128 sampel dari data audio, pemisahan antara dua sampel (frekuensi persampelan) bergantung pada frekuensi minat. Dalam kes ini, kita menggunakan jarak antara dua sampel digunakan untuk menerapkan fungsi tetingkap Hann serta pengiraan amplitud / RMS. Kod ini juga melakukan zeroing kasar dengan mengurangkan 500 dari nilai analogread. Nilai ini boleh diubah jika diperlukan. Untuk kes biasa, nilai ini berfungsi dengan baik. Selanjutnya, beberapa penundaan perlu ditambahkan untuk memiliki frekuensi pengambilan sampel sekitar 1200Hz. sekiranya frekuensi persampelan 1200Hz maksimum frekuensi 600 HZ dapat dikesan.

untuk (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // kasar sifar peralihan jumlah1 = jumlah1 + a; // ke nilai purata sum2 = sum2 + a * a; // hingga nilai RMS a = a * (sin (i * 3.14 / 128) * sin (i * 3.14 / 128)); // tetingkap Hann di = 4 * a; // skala untuk kelewatan penukaran float ke intMikrodetik (195); // berdasarkan julat frekuensi operasi}

2. FFT:

Setelah data siap, FFT dilakukan menggunakan EasyFFT. Fungsi EasyFFT ini diubahsuai untuk memperbaiki FFT untuk 128 sampel. Kodnya juga diubahsuai untuk mengurangkan penggunaan memori. Fungsi EasyFFT yang asli dirancang untuk mempunyai hingga 1028 sampel (dengan papan serasi), sementara kami hanya memerlukan 128 sampel. kod ini mengurangkan penggunaan memori sekitar 20% berbanding fungsi EasyFFT yang asal.

Setelah FFT selesai, kod tersebut mengembalikan 5 puncak frekuensi paling dominan untuk analisis selanjutnya. Frekuensi ini disusun dalam urutan amplitud menurun.

3. Untuk setiap puncak, kod mengesan kemungkinan nota yang berkaitan dengannya. kod ini hanya mengimbas hingga 1200 Hz. Tidak perlu mencatat sama dengan frekuensi dengan amplitud maksimum.

Semua frekuensi dipetakan antara 0 hingga 255, di sini oktaf pertama dikesan, misalnya, 65.4 Hz hingga 130.8 mewakili satu oktaf, 130.8 Hz hingga 261.6 Hz mewakili yang lain. Untuk setiap oktaf, frekuensi dipetakan dari 0 hingga 255. di sini pemetaan bermula dari C hingga C '.

jika (f_peaks > 1040) {f_peaks = 0;} jika (f_peaks > = 65.4 && f_peaks = 130.8 && f_peaks = 261.6 && f_peaks = 523.25 && f_peaks = 1046 && f_peaks <= 2093) {f_peaks = 255 * ((f_peaks / 1046) -1);}

Nilai array NoteV digunakan untuk menetapkan nota ke frekuensi yang dikesan.

bait NoteV [13] = {8, 23, 40, 57, 76, 96, 116, 138, 162, 187, 213, 241, 255};

4. Setelah mengira nota untuk setiap frekuensi, mungkin terdapat banyak frekuensi yang ada yang menunjukkan nota yang sama. Untuk mempunyai kod output yang tepat juga mempertimbangkan pengulangan. Kod menambahkan semua nilai frekuensi berdasarkan susunan amplitud dan pengulangan dan memuncak nota dengan amplitud maksimum.

Langkah 2: Permohonan

Menggunakan kod adalah lurus ke depan, bagaimanapun, terdapat juga beberapa batasan yang perlu diingat semasa menggunakannya. Kod boleh disalin kerana digunakan untuk pengesanan nota. Perkara di bawah perlu dipertimbangkan semasa menggunakannya.

1. Tugasan Pin:

Berdasarkan penugasan Pin yang dilampirkan perlu diubahsuai. Untuk percubaan saya, saya menyimpannya ke Analog pin 7, batal persediaan () {Serial.begin (250000); Mic_pin = A7; }

2. Kepekaan mikrofon:

Kepekaan mikrofon perlu diubah bentuk gelombang sedemikian dapat dihasilkan dengan amplitud yang baik. Selalunya, modul Mikrofon dilengkapi dengan tetapan kepekaan. kepekaan yang sesuai untuk dipilih sedemikian rupa sehingga isyarat tidak terlalu kecil dan juga tidak terpotong kerana amplitud yang lebih tinggi.

3. Ambang Amplitud:

Kod ini diaktifkan hanya jika amplitud isyarat jika cukup tinggi. tetapan ini perlu ditetapkan secara manual oleh pengguna. nilai ini bergantung pada kepekaan mikrofon dan juga aplikasi.

jika (sum2-sum1> 5) {

..

dalam kod di atas, sum2 memberikan nilai RMS sementara jumlah 1 memberikan nilai min. jadi perbezaan antara kedua-dua nilai ini memberikan amplitud isyarat suara. dalam kes saya, ia berfungsi dengan baik dengan nilai amplitud sekitar 5.

4. Secara lalai, kod ini akan mencetak nota yang dikesan. namun, jika anda merancang untuk menggunakan nota tersebut untuk tujuan lain, nombor yang diberikan secara langsung harus digunakan. contohnya C = 0; C # = 1, D = 2, D # = 3 dan seterusnya.

5. Sekiranya instrumen mempunyai frekuensi yang lebih tinggi, kod tersebut dapat memberikan output yang salah. frekuensi maksimum dibatasi oleh frekuensi persampelan. jadi anda mungkin bermain di bawah nilai kelewatan untuk mendapatkan output yang optimum. dalam kelewatan kod di bawah 195 mikrodetik. yang mungkin diubah untuk mendapatkan output yang optimum. Ini akan mempengaruhi keseluruhan masa pelaksanaan.

{a = analogRead (Mic_pin) -500; // peralihan sifar kasar

jumlah1 = jumlah1 + a; // ke nilai purata sum2 = sum2 + a * a; // hingga nilai RMS a = a * (sin (i * 3.14 / 128) * sin (i * 3.14 / 128)); // tetingkap Hann di = 4 * a; // skala untuk kelewatan penukaran float ke intMikrodetik (195); // berdasarkan julat frekuensi operasi}

6. kod ini hanya akan berfungsi hingga frekuensi 2000Hz. dengan menghilangkan kelewatan antara pensampelan sekitar 3-4 kHz frekuensi persampelan dapat diperoleh.

Langkah berjaga-berjaga:

  • Seperti yang disebutkan dalam tutorial EasyFFT, FFT memakan banyak memori Arduino. Oleh itu, jika anda mempunyai program yang perlu menyimpan beberapa nilai, disyorkan untuk menggunakan papan dengan memori yang lebih tinggi.
  • Kod ini mungkin berfungsi dengan baik untuk satu instrumen / vokalis dan buruk untuk yang lain. Pengesanan yang tepat pada masa nyata tidak mungkin dilakukan kerana had pengiraan.

Langkah 3: Summery

Pengesanan nota adalah kerja intensif secara komputasi, mendapatkan output masa nyata sangat sukar terutama pada Arduino. Kod ini dapat memberikan sekitar 6.6 sampel / saat (untuk penangguhan 195 mikrodetik ditambahkan). kod ini berfungsi dengan baik dengan piano dan beberapa instrumen lain.

Saya harap kod dan tutorial ini dapat membantu projek anda yang berkaitan dengan muzik. sekiranya ada keraguan atau cadangan jangan ragu untuk memberi komen atau mesej.

Dalam tutorial yang akan datang, saya akan mengubah kod ini untuk pengesanan kord muzik. jadi nantikan.

Disyorkan: