Daftar Isi:
- Perlengkapan
- Langkah 1: Bangun Perangkat Keras untuk Detektor Catatan Musik
- Langkah 2: Program Detektor Catatan Musik
- Langkah 3: Siapkan Detektor Catatan Musik
Video: Detektor Catatan Musik: 3 Langkah
2024 Pengarang: John Day | [email protected]. Terakhir diubah: 2024-01-30 09:54
Buat kagum teman dan keluarga Anda dengan proyek ini yang mendeteksi nada yang dimainkan oleh instrumen. Proyek ini akan menampilkan perkiraan frekuensi serta not musik yang dimainkan pada keyboard elektronik, aplikasi piano, atau instrumen lainnya.
rincian
Untuk proyek ini, output analog dari detektor modul suara dikirim ke input analog A0 dari Arduino Uno. Sinyal analog diambil sampelnya dan dikuantisasi (digitisasi). Autokorelasi, pembobotan dan kode tuning digunakan untuk mencari frekuensi fundamental menggunakan 3 periode pertama. Perkiraan frekuensi dasar kemudian dibandingkan dengan frekuensi dalam rentang oktaf 3, 4, dan 5 untuk menentukan frekuensi not musik terdekat. Akhirnya catatan tebakan untuk frekuensi terdekat dicetak ke layar.
Catatan: Instruksi ini hanya berfokus pada bagaimana membangun proyek. Untuk informasi lebih lanjut tentang detail dan justifikasi desain, silakan kunjungi tautan ini: Informasi Lebih Lanjut
Perlengkapan
- (1) Arduino Uno (atau Genuino Uno)
- (1) Sensor Mikrofon DEVMO Kompatibel dengan Modul Deteksi Suara Sensitivitas Tinggi
- (1) Papan tempat memotong roti tanpa solder
- (1) Kabel USB-A ke B
- Kabel jumper
- Sumber musik (piano, keyboard, atau aplikasi paino dengan speaker)
- (1) Komputer atau laptop
Langkah 1: Bangun Perangkat Keras untuk Detektor Catatan Musik
Menggunakan Arduino Uno, kabel koneksi, papan tempat memotong roti tanpa solder, dan Modul Deteksi Suara Sensitivitas Tinggi Sensor Mikrofon DEVMO (atau serupa) membuat sirkuit yang ditunjukkan pada gambar ini
Langkah 2: Program Detektor Catatan Musik
Di Arduino IDE, tambahkan kode berikut.
gistfile1.txt
/* |
Nama File/Sketsa: MusicalNoteDetector |
Versi No.: v1.0 Dibuat 7 Juni 2020 |
Penulis Asli: Clyde A. Lettsome, PhD, PE, MEM |
Deskripsi: Kode/sketsa ini menampilkan perkiraan frekuensi serta not musik yang dimainkan pada keyboard elektronik atau aplikasi piano. Untuk proyek ini, output analog dari |
detektor modul suara dikirim ke input analog A0 dari Arduino Uno. Sinyal analog diambil sampelnya dan dikuantisasi (digitisasi). Autokorelasi, pembobotan, dan kode penyetelan digunakan untuk |
cari frekuensi dasar menggunakan 3 periode pertama. Perkiraan frekuensi dasar kemudian dibandingkan dengan frekuensi dalam rentang oktaf 3, 4, dan 5 untuk menentukan musik terdekat |
frekuensi catatan. Akhirnya catatan tebakan untuk frekuensi terdekat dicetak ke layar. |
Lisensi: Program ini adalah perangkat lunak bebas; Anda dapat mendistribusikan ulang dan/atau memodifikasinya di bawah persyaratan GNU General Public License (GPL) versi 3, atau yang lebih baru |
versi pilihan Anda, sebagaimana diterbitkan oleh Free Software Foundation. |
Catatan: Hak Cipta (c) 2020 oleh C. A. Lettsome Services, LLC |
Untuk informasi lebih lanjut kunjungi |
*/ |
#define SAMPLES 128 //Max 128 untuk Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 //Fs = Berdasarkan Nyquist, harus 2 kali frekuensi tertinggi yang diharapkan. |
#define OFFSETSAMPLES 40 //digunakan untuk tujuan kalibrasi |
#define TUNER -3 //Sesuaikan hingga C3 adalah 130.50 |
periode sampling mengambang; |
microSeconds panjang yang tidak ditandatangani; |
int X[SAMPEL]; //buat vektor ukuran SAMPEL untuk menampung nilai nyata |
float autoCorr[SAMPEL]; //buat vektor dengan ukuran SAMPEL untuk menampung nilai imajiner |
float tersimpanNoteFreq[12] = {130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185, 196, 207.65, 220, 233.08, 246.94}; |
int sumOffSet = 0; |
int offSet[OFFSETSAMPLES]; //membuat vektor offset |
int avgOffSet; //membuat vektor offset |
int i, k, periodEnd, periodBegin, period, adjuster, noteLocation, octaveRange; |
float maxValue, minValue; |
jumlah panjang; |
int ambang = 0; |
int jumlah Siklus = 0; |
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total; |
byte state_machine = 0; |
int sampelPerPeriod = 0; |
batalkan pengaturan() |
{ |
Serial.begin(115200); //115200 Baud rate untuk Serial Monitor |
} |
lingkaran kosong() |
{ |
//***************************************************************** |
//Bagian Kalibrasi |
//***************************************************************** |
Serial.println("Calabration. Harap tidak memainkan not apapun selama kalibrasi."); |
untuk (i = 0; i < OFFSETSAMPLES; i++) |
{ |
offSet = analogRead(0); //Membaca nilai dari pin analog 0 (A0), kuantisasi dan simpan sebagai suku nyata. |
//Serial.println(offSet); //gunakan ini untuk menyesuaikan modul deteksi suara menjadi sekitar setengah atau 512 saat tidak ada suara yang diputar. |
sumOffSet = sumOffSet + offSet; |
} |
sampelPerPeriode = 0; |
nilai maks = 0; |
//***************************************************************** |
//Bersiaplah untuk menerima masukan dari A0 |
//***************************************************************** |
avgOffSet = bulat(sumOffSet / OFFSETSAMPLES); |
Serial.println("Menghitung mundur."); |
penundaan (1000); //jeda selama 1 detik |
Serial.println("3"); |
penundaan (1000); //jeda selama 1 detik |
Serial.println("2"); |
penundaan (1000); //jeda untuk 1 |
Serial.println("1"); |
penundaan (1000); //jeda selama 1 detik |
Serial.println("Mainkan catatanmu!"); |
penundaan (250); //jeda selama 1/4 detik untuk waktu reaksi |
//***************************************************************** |
//Kumpulkan sampel SAMPEL dari A0 dengan periode sampel Periode pengambilan sampel |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; //Periode dalam mikrodetik |
untuk (i = 0; i < SAMPEL; i++) |
{ |
mikrodetik = mikro(); //Mengembalikan jumlah mikrodetik sejak papan Arduino mulai menjalankan skrip saat ini. |
X = analogRead(0); //Membaca nilai dari pin analog 0 (A0), kuantisasi dan simpan sebagai suku nyata. |
/*sisa waktu tunggu antar sampel jika perlu dalam hitungan detik */ |
while (micros() < (microSeconds + (samplingPeriod * 1000000)))) |
{ |
// tidak melakukan apa-apa, tunggu saja |
} |
} |
//***************************************************************** |
//Fungsi Autokorelasi |
//***************************************************************** |
untuk (i = 0; i < SAMPEL; i++) //i=delay |
{ |
jumlah = 0; |
for (k = 0; k < SAMPLES - i; k++) //Mencocokkan sinyal dengan sinyal tertunda |
{ |
jumlah = jumlah + (((X[k]) - avgOffSet) * ((X[k + i]) - avgOffSet)); //X[k] adalah sinyal dan X[k+i] adalah versi tertunda |
} |
autoCorr = jumlah / SAMPEL; |
// Mesin Status Deteksi Puncak Pertama |
if (state_machine==0 && i == 0) |
{ |
ambang = autoCorr * 0,5; |
negara_mesin = 1; |
} |
else if (state_machine == 1 && i>0 && thresh 0) //state_machine=1, cari 1 periode untuk menggunakan siklus pertama |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 1&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
periodeMulai = i-1; |
negara_mesin = 2; |
numOfCycles = 1; |
sampelPerPeriod = (periodBegin - 0); |
periode = sampelPeriode; |
pengatur = TUNER+(50,04 * exp(-0,102 * sampelPerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod))-adjuster; // f = fs/N |
} |
else if (state_machine == 2 && i>0 && thresh 0) //state_machine=2, cari 2 periode untuk siklus 1 dan 2 |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 2&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
periodeEnd = i-1; |
negara_mesin = 3; |
numOfCycles = 2; |
sampelPerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-adjuster; // f = (2*fs)/(2*N) |
nilai maks = 0; |
} |
else if (state_machine == 3 && i>0 && thresh 0) //state_machine=3, cari 3 periode untuk siklus 1, 2 dan 3 |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 3&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
periodeEnd = i-1; |
negara_mesin = 4; |
numOfCycles = 3; |
sampelPerPeriod = (periodEnd - 0); |
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-adjuster; // f = (3*fs)/(3*N) |
} |
} |
//***************************************************************** |
//Analisis Hasil |
//***************************************************************** |
jika (sampelPerPeriod == 0) |
{ |
Serial.println("Hmm….. Saya tidak yakin. Apakah Anda mencoba menipu saya?"); |
} |
lain |
{ |
//siapkan fungsi pembobotan |
jumlah = 0; |
jika (frekuensi sinyal !=0) |
{ |
jumlah = 1; |
} |
jika(sinyalFrekuensi2 !=0) |
{ |
jumlah = jumlah + 2; |
} |
jika (sinyalFrekuensi3 !=0) |
{ |
jumlah = jumlah + 3; |
} |
//hitung frekuensi menggunakan fungsi pembobotan |
signalFrequencyGuess = ((1/total) * signalFrequency) + ((2/total) * signalFrequency2) + ((3/total) * signalFrequency3); //menemukan frekuensi berbobot |
Serial.print("Catatan yang Anda mainkan kira-kira "); |
Serial.print(signalFrequencyGuess); // Cetak tebakan frekuensi. |
Serial.println("Hz."); |
//menemukan rentang oktaf berdasarkan tebakan |
rentang oktaf=3; |
while (!(signalFrequencyGuess >= storedNoteFreq[0]-7 && signalFrequencyGuess <= storedNoteFreq[11]+7)) |
{ |
untuk(i = 0; i < 12; i++) |
{ |
disimpanNoteFreq = 2 * disimpanNoteFreq; |
} |
rentang oktaf++; |
} |
//Temukan catatan terdekat |
minNilai = 10000000; |
catatanLokasi = 0; |
untuk (i = 0; i < 12; i++) |
{ |
if(minValue> abs(signalFrequencyGuess-storedNoteFreq)) |
{ |
minValue = abs(signalFrequencyGuess-storedNoteFreq); |
catatanLokasi = i; |
} |
} |
//Cetak catatan |
Serial.print("Saya pikir Anda bermain "); |
jika(catatanLokasi==0) |
{ |
Serial.print("C"); |
} |
lain jika(catatanLocation==1) |
{ |
Serial.print("C#"); |
} |
lain jika (catatanLocation==2) |
{ |
Serial.print("D"); |
} |
lain jika(catatanLocation==3) |
{ |
Serial.print("D#"); |
} |
lain jika (catatanLocation==4) |
{ |
Serial.print("E"); |
} |
lain jika (catatanLocation==5) |
{ |
Serial.print("F"); |
} |
lain jika (catatanLocation==6) |
{ |
Serial.print("F#"); |
} |
lain jika(catatanLocation==7) |
{ |
Serial.print("G"); |
} |
lain jika (catatanLocation==8) |
{ |
Serial.print("G#"); |
} |
lain jika(catatanLocation==9) |
{ |
Serial.print("A"); |
} |
lain jika (catatanLocation==10) |
{ |
Serial.print("A#"); |
} |
lain jika (catatanLocation==11) |
{ |
Serial.print("B"); |
} |
Serial.println(Rentang oktaf); |
} |
//***************************************************************** |
//Berhenti disini. Tekan tombol reset pada Arduino untuk memulai kembali |
//***************************************************************** |
sementara (1); |
} |
lihat rawgistfile1.txt yang dihosting dengan ❤ oleh GitHub
Langkah 3: Siapkan Detektor Catatan Musik
Hubungkan Arduino Uno ke PC dengan kode yang ditulis atau dimuat di Arduino IDE. Kompilasi dan unggah kode ke Arduino. Tempatkan sirkuit dekat dengan sumber musik. Catatan: Dalam video pengantar, saya menggunakan aplikasi yang diinstal di tablet bersama dengan speaker PC sebagai sumber musik saya. Tekan tombol reset pada Papan Arduino dan kemudian mainkan nada pada sumber musik. Setelah beberapa detik, Musical Note Detector akan menampilkan not yang dimainkan dan frekuensinya.
Direkomendasikan:
Catatan Cuaca: 7 Langkah (dengan Gambar)
Catatan Cuaca: Ini adalah kombinasi stasiun cuaca dan pengingat. Kita semua dapat memeriksa cuaca di ponsel kita, tetapi kadang-kadang dan terutama ketika seseorang mencoba keluar dari pintu, yang diperlukan hanyalah cara cepat untuk mengetahui kondisi cuaca. Stasiun cuaca ini mendukung
Detektor Catatan Musik Arduino: 3 Langkah
Arduino Music Notes Detector: 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 va
Cara: Membuat Karya Luar Biasa di Animal Jam! (CATATAN: DIPERBARUI 2020): 3 Langkah
Cara: Membuat Karya Luar Biasa di Animal Jam! (CATATAN: DIPERBARUI 2020): Selai hewan adalah dunia virtual tentang hewan. Anda dapat membeli hewan dengan permata atau berlian dan menyesuaikannya dengan pakaian yang Anda beli di toko virtual! Saya tidak pernah benar-benar "bermain" Animal Jam, saya hanya suka membuat Karya! Hari ini saya akan menunjukkan kepada Anda
Catatan Musik Berkedip: 5 Langkah
Musik Berkedip Catatan: Bahan: 4 lampu LED (turquoise, biru) Mesin CNC Wire SolidWorks Printer 3D Solder Besi dan solder 2 resistor 200 Ohm Lem panas Baterai 9 Volt dan konektor jepret BorProyek ini sangat sederhana dan tidak membutuhkan waktu yang lama
Kotak / Instrumen Musik 6 Catatan Genggam (Mudah Dibuat & Ditingkatkan!): 5 Langkah (dengan Gambar)
Kotak Musik / Instrumen Genggam 6 Catatan (Mudah Dibuat & Ditingkatkan!): Hai! Terinspirasi oleh Martin Molin, anggota band Swedia bernama Wintergatan, baru-baru ini saya jatuh cinta dengan kotak musik dan segala sesuatu tentangnya. Orang yang membuat lagu untuk kotak musik masih menggunakan cara kuno untuk meninju lagu bukan