Daftar Isi:

Detektor Catatan Musik Arduino: 3 Langkah
Detektor Catatan Musik Arduino: 3 Langkah

Video: Detektor Catatan Musik Arduino: 3 Langkah

Video: Detektor Catatan Musik Arduino: 3 Langkah
Video: Amazing arduino project 2024, November
Anonim
Image
Image

Mendeteksi not musik dari sinyal audio sulit dilakukan terutama pada Arduino karena keterbatasan memori dan daya pemrosesan. Umumnya, nada tersebut bukan gelombang sinus murni yang membuat pendeteksian menjadi sulit. Jika kita mengambil transformasi frekuensi dari berbagai alat musik, mungkin mengandung beberapa harmonik berdasarkan nada yang dimainkan. Setiap instrumen memiliki kombinasi khas dari berbagai harmonik. Dalam kode ini, saya mencoba membuat program yang dapat mencakup instrumen sebanyak mungkin. Anda dapat merujuk video terlampir di mana saya mencoba menguji berbagai jenis instrumen, berbagai jenis nada yang dihasilkan oleh keyboard, dan bahkan suara vokal diperiksa. Akurasi deteksi bervariasi dari instrumen ke instrumen. Untuk beberapa instrumen (yaitu piano) dalam rentang terbatas (200-500Hz) akurat, sementara beberapa instrumen memiliki akurasi rendah (yaitu Harmonika).

Kode ini menggunakan kode FFT yang dikembangkan sebelumnya yang disebut EasyFFT.

Demonstrasi kode ditampilkan dalam video di atas dengan berbagai jenis suara instrumen serta vokal.

Perlengkapan

- Arduino Nano/Uno atau lebih tinggi

- Modul mikrofon untuk Arduino

Langkah 1: Algoritma untuk Deteksi Catatan

Seperti disebutkan pada langkah sebelumnya, deteksi sulit karena adanya beberapa frekuensi dalam sampel audio.

Program ini bekerja dalam alur berikut:

1. Akuisisi data:

- bagian ini mengambil 128 sampel dari data audio, pemisahan antara dua sampel (frekuensi sampling) tergantung pada frekuensi yang diinginkan. Dalam hal ini, kami menggunakan jarak antara dua sampel yang digunakan untuk menerapkan fungsi jendela Hann serta perhitungan amplitudo/RMS. Kode ini juga melakukan zeroing kasar dengan mengurangi 500 dari nilai analogread. Nilai ini dapat diubah jika diperlukan. Untuk kasus tipikal, nilai ini berfungsi dengan baik. Selanjutnya, beberapa penundaan perlu ditambahkan untuk memiliki frekuensi sampling sekitar 1200Hz. dalam kasus frekuensi sampling 1200Hz, frekuensi maksimum 600 HZ dapat dideteksi.

for(int i=0;i<128;i++) { a=analogRead(Mic_pin)-500; //pergeseran nol kasar sum1=sum1+a; //untuk nilai rata-rata sum2=sum2+a*a; // ke nilai RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Jendela Hann di=4*a; // penskalaan untuk float ke int konversi delayMicroseconds(195); // berdasarkan rentang frekuensi operasi }

2. FFT:

Setelah data siap, FFT dilakukan menggunakan EasyFFT. Fungsi EasyFFT ini dimodifikasi untuk memperbaiki FFT untuk 128 sampel. Kode juga dimodifikasi untuk mengurangi konsumsi memori. Fungsi EasyFFT asli dirancang untuk memiliki hingga 1028 sampel (dengan papan yang kompatibel), sementara kami hanya membutuhkan 128 sampel. kode ini mengurangi konsumsi memori sekitar 20% dibandingkan dengan fungsi EasyFFT asli.

Setelah FFT selesai, kode mengembalikan 5 puncak frekuensi paling dominan teratas untuk analisis lebih lanjut. Frekuensi ini diatur dalam urutan amplitudo menurun.

3. Untuk setiap puncak, kode mendeteksi nada yang mungkin terkait dengannya. kode ini hanya memindai hingga 1200 Hz. Tidak perlu dicatat sama dengan frekuensi dengan amplitudo maks.

Semua frekuensi dipetakan antara 0 hingga 255, di sini oktaf pertama terdeteksi, 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 dimulai dari C ke C'.

if(f_peaks>1040){f_peaks=0;} if(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 larik NoteV digunakan untuk menetapkan nada ke frekuensi yang terdeteksi.

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

4. Setelah menghitung nada untuk setiap frekuensi, mungkin ada beberapa frekuensi yang menunjukkan nada yang sama. Untuk memiliki kode keluaran yang akurat juga mempertimbangkan pengulangan. Kode menjumlahkan semua nilai frekuensi berdasarkan urutan amplitudo dan pengulangan dan memuncak catatan dengan amplitudo maksimum.

Langkah 2: Aplikasi

Menggunakan kode itu mudah, namun, ada juga beberapa batasan yang perlu diingat saat menggunakannya. Kode dapat disalin karena digunakan untuk deteksi catatan. Poin-poin di bawah ini perlu dipertimbangkan saat menggunakannya.

1. Penugasan Pin:

Berdasarkan penugasan Pin terlampir perlu diubah. Untuk percobaan saya, saya menyimpannya di pin Analog 7, void setup() {Serial.begin(250000); Pin_mikro = A7; }

2. Sensitivitas mikrofon:

Sensitivitas mikrofon perlu dimodifikasi agar bentuk gelombang dapat dihasilkan dengan amplitudo yang baik. Sebagian besar, modul Mikrofon dilengkapi dengan pengaturan sensitivitas. sensitivitas yang tepat untuk dipilih sehingga sinyal tidak terlalu kecil dan juga tidak terputus karena amplitudo yang lebih tinggi.

3. Ambang amplitudo:

Kode ini hanya aktif jika amplitudo sinyal cukup tinggi. pengaturan ini perlu diatur secara manual oleh pengguna. nilai ini tergantung pada sensitivitas mikrofon serta aplikasi.

if(jumlah2-jumlah1>5){

..

dalam kode di atas, sum2 memberikan nilai RMS sedangkan sum 1 memberikan nilai rata-rata. jadi perbedaan antara kedua nilai ini memberikan amplitudo sinyal suara. dalam kasus saya, ini berfungsi dengan baik dengan nilai amplitudo sekitar 5.

4. Secara default, kode ini akan mencetak catatan yang terdeteksi. namun, jika Anda berencana menggunakan catatan untuk tujuan lain, nomor yang ditetapkan secara langsung harus digunakan. misalnya C=0;C#=1, D=2, D#=3 dan seterusnya.

5. Jika instrumen memiliki frekuensi yang lebih tinggi, kode dapat memberikan output yang salah. frekuensi maksimum dibatasi oleh frekuensi sampling. sehingga Anda dapat bermain-main di bawah nilai delay untuk mendapatkan output yang optimal. di bawah kode penundaan 195 mikrodetik. yang dapat di-tweak untuk mendapatkan output yang optimal. Ini akan mempengaruhi waktu eksekusi secara keseluruhan.

{ a=analogRead(Mic_pin)-500; //pergeseran nol kasar

jumlah1=jumlah1+a; //untuk nilai rata-rata sum2=sum2+a*a; // ke nilai RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Jendela Hann di=4*a; // penskalaan untuk float ke int konversi delayMicroseconds(195); // berdasarkan rentang frekuensi operasi }

6. kode ini hanya akan bekerja sampai frekuensi 2000Hz. dengan menghilangkan penundaan antara sampling sekitar 3-4 kHz frekuensi sampling dapat diperoleh.

Tindakan pencegahan:

  • Seperti yang disebutkan dalam tutorial EasyFFT, FFT memakan banyak memori Arduino. Jadi, jika Anda memiliki program yang perlu menyimpan beberapa nilai, disarankan untuk menggunakan papan dengan memori yang lebih tinggi.
  • Kode ini dapat bekerja dengan baik untuk satu instrumen/vokalis dan buruk untuk yang lain. Deteksi akurat waktu nyata tidak dimungkinkan karena keterbatasan komputasi.

Langkah 3: Musim Panas

Deteksi catatan adalah pekerjaan intensif komputasi, mendapatkan output waktu nyata sangat sulit terutama pada Arduino. Kode ini dapat memberikan sekitar 6,6 sampel / detik (untuk penundaan 195 mikrodetik ditambahkan). kode ini bekerja dengan baik dengan piano dan beberapa instrumen lainnya.

Saya harap kode dan tutorial ini bermanfaat dalam proyek Anda yang terkait dengan musik. jika ada keraguan atau saran jangan ragu untuk berkomentar atau mengirim pesan.

Dalam tutorial yang akan datang, saya akan memodifikasi kode ini untuk deteksi akord musik. jadi tetap disini.

Direkomendasikan: