Sadržaj:

Arduino detektor glazbenih bilješki: 3 koraka
Arduino detektor glazbenih bilješki: 3 koraka

Video: Arduino detektor glazbenih bilješki: 3 koraka

Video: Arduino detektor glazbenih bilješki: 3 koraka
Video: 30 невероятных проектов Arduino, которые вы должны попробовать 2024, Studeni
Anonim
Image
Image

Otkrivanje glazbenih nota iz audio signala teško je učiniti posebno na Arduinu zbog ograničene memorije i procesorske snage. Općenito, nota nije čisti sinusni val koji otežava otkrivanje. Uzmemo li frekvencijsku transformaciju različitih glazbenih instrumenata, ona može sadržavati više harmonika na temelju note koja se svira. Svaki instrument ima svoju kombinaciju različitih harmonika. U ovom sam kodu pokušao napraviti program koji može pokriti što više instrumenata. Možete pogledati priloženi video u kojem sam pokušao testirati različite vrste instrumenata, provjeravaju se različite vrste tonova koje stvara tipkovnica, pa čak i zvuk vokala. Točnost otkrivanja razlikuje se od instrumenta do instrumenta. Za neki instrument (tj. Klavir) u ograničenom rasponu (200-500Hz) točan je, dok za neki instrument ima nisku točnost (npr. Harmonika).

Ovaj kôd koristi prethodno razvijeni FFT kod nazvan EasyFFT.

Demonstracija koda prikazana je u gornjem videu s različitim vrstama zvuka instrumenta kao i vokalom.

Pribor

- Arduino Nano/Uno ili iznad

- Modul mikrofona za Arduino

Korak 1: Algoritam za otkrivanje bilješki

Kao što je spomenuto u prethodnom koraku, otkrivanje je teško zbog prisutnosti više frekvencija u audio uzorcima.

Program radi u sljedećem tijeku:

1. Prikupljanje podataka:

- ovaj odjeljak uzima 128 uzoraka iz audio podataka, razdvajanje dva uzorka (frekvencija uzorkovanja) ovisno o frekvenciji koja vas zanima. U ovom slučaju, razmak između dva uzorka koristi se za primjenu Hannove funkcije prozora, kao i za izračunavanje amplitude/RMS. Ovaj kôd također vrši grubo nuliranje oduzimanjem 500 od vrijednosti analognog čitanja. Ova se vrijednost može promijeniti ako je potrebno. U tipičnom slučaju, ove vrijednosti dobro funkcioniraju. Nadalje, potrebno je dodati određeno kašnjenje kako bi frekvencija uzorkovanja bila oko 1200Hz. u slučaju frekvencije uzorkovanja 1200Hz može se detektirati maksimalna frekvencija od 600 HZ.

for (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // gruba promjena nule sum1 = sum1+a; // na prosječnu vrijednost sum2 = sum2+a*a; // u RMS vrijednost a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // Hannov prozor u = 4*a; // skaliranje za kašnjenje pretvorbe float u intMicroseconds (195); // na temelju radnog frekvencijskog raspona}

2. FFT:

Kad su podaci spremni, FFT se izvodi pomoću EasyFFT -a. Ova funkcija EasyFFT modificirana je kako bi popravila FFT za 128 uzoraka. Kôd se također mijenja kako bi se smanjila potrošnja memorije. Originalna funkcija EasyFFT dizajnirana je za do 1028 uzoraka (s kompatibilnom pločom), dok nam je potrebno samo 128 uzoraka. ovaj kod smanjuje potrošnju memorije za oko 20% u usporedbi s izvornom funkcijom EasyFFT.

Nakon što se FFT završi, kod vraća prvih 5 najdominantnijih vrhova frekvencije za daljnju analizu. Ove su frekvencije raspoređene prema silaznom redoslijedu amplitude.

3. Kod svakog vrha kôd detektira moguće bilješke povezane s njim. ovaj kod skenira samo do 1200 Hz. Nije potrebno imati istu bilješku kao frekvencija s maksimalnom amplitudom.

Sve su frekvencije preslikane između 0 i 255, ovdje se detektira prva oktava, na primjer, 65,4 Hz do 130,8 predstavlja jednu oktavu, 130,8 Hz do 261,6 Hz drugu. Za svaku oktavu frekvencije su preslikane od 0 do 255. ovdje se preslikavaju počevši od C do 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);}

Vrijednosti polja NoteV koriste se za dodjeljivanje note otkrivenim frekvencijama.

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

4. Nakon izračuna note za svaku frekvenciju može se dogoditi da postoji više frekvencija koje sugeriraju istu notu. Za točan izlazni kod također se razmatraju ponavljanja. Kôd zbraja sve frekvencijske vrijednosti na temelju redoslijeda amplituda i ponavljanja te naglašava notu maksimalnom amplitudom.

Korak 2: Primjena

Korištenje koda je jednostavno, međutim, postoje i više ograničenja koja treba imati na umu pri tome. Kôd se može kopirati jer se koristi za otkrivanje bilješki. Prilikom korištenja potrebno je uzeti u obzir dolje navedene točke.

1. Dodjela pinova:

Na temelju priloženog dodjeljivanja pin -a potrebno je izmijeniti. Za svoj sam eksperiment držao analogni pin 7, void setup () {Serial.begin (250000); Mic_pin = A7; }

2. Osjetljivost mikrofona:

Osjetljivost mikrofona treba mijenjati, tako da se valni oblik može generirati s dobrom amplitudom. Uglavnom, modul mikrofona dolazi s postavkom osjetljivosti. odgovarajuću osjetljivost odabrati tako da signal nije premalen i također se ne odsiječe zbog veće amplitude.

3. Prag amplitude:

Ovaj se kôd aktivira samo ako je amplituda signala dovoljno visoka. ovu postavku korisnik mora postaviti ručno. ova vrijednost ovisi o osjetljivosti mikrofona, kao io primjeni.

if (sum2-sum1> 5) {

..

u gornjem kodu, sum2 daje RMS vrijednost dok zbroj 1 daje srednju vrijednost. pa razlika između ove dvije vrijednosti daje amplitudu zvučnog signala. u mom slučaju radi ispravno s vrijednošću amplitude oko 5.

4. Ovaj kôd prema zadanim postavkama ispisuje otkrivenu bilješku. međutim, ako bilješku namjeravate koristiti u neku drugu svrhu, treba koristiti izravno dodijeljeni broj. na primjer C = 0; C#= 1, D = 2, D#= 3 i dalje.

5. Ako instrument ima veću frekvenciju, kôd može dati lažni izlaz. najveća frekvencija ograničena je frekvencijom uzorkovanja. pa se možete poigrati ispod vrijednosti kašnjenja kako biste postigli optimalan učinak. u donjem kašnjenju od 195 mikrosekundi. koji se može prilagoditi kako bi se postigao optimalan učinak. To će utjecati na ukupno vrijeme izvođenja.

{a = analogno čitanje (Mic_pin) -500; // grubi pomak nule

zbroj1 = zbroj1+a; // na prosječnu vrijednost sum2 = sum2+a*a; // u RMS vrijednost a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // Hannov prozor u = 4*a; // skaliranje za kašnjenje pretvorbe float u intMicroseconds (195); // na temelju radnog frekvencijskog raspona}

6. ovaj kôd će raditi samo do frekvencije 2000Hz. uklanjanjem kašnjenja između uzorkovanja može se dobiti oko 3-4 kHz frekvencija uzorkovanja.

Mjere opreza:

  • Kao što je spomenuto u vodiču EasyFFT, FFT jede ogromnu količinu memorije za Arduino. Dakle, ako imate program koji treba pohraniti neke vrijednosti, preporučuje se upotreba ploče s većom memorijom.
  • Ovaj kôd može dobro funkcionirati za jedan instrument/vokal, a loše za drugi. Točno otkrivanje u stvarnom vremenu nije moguće zbog računalnih ograničenja.

Korak 3: Ljeto

Otkrivanje bilješki računalno je intenzivan posao, dobivanje rezultata u stvarnom vremenu vrlo je teško, posebno na Arduinu. Ovaj kôd može dati oko 6,6 uzoraka /sekundi (za 195 mikrosekundi dodano kašnjenje). ovaj kôd dobro funkcionira s klavirom i nekim drugim instrumentima.

Nadam se da će vam ovaj kôd i vodič biti od pomoći u vašem projektu vezanom za glazbu. u slučaju bilo kakve sumnje ili prijedloga slobodno komentirajte ili pošaljite poruku.

U nadolazećem vodiču izmijenit ću ovaj kôd za otkrivanje glazbenih akorda. pa ostanite uz nas.

Preporučeni: