Sadržaj:

Arduino detektor muzičkih bilješki: 3 koraka
Arduino detektor muzičkih bilješki: 3 koraka

Video: Arduino detektor muzičkih bilješki: 3 koraka

Video: Arduino detektor muzičkih bilješki: 3 koraka
Video: iPhone Introducing❓ Steve Jobs in 2007❕ #part6 (Full Subtitle) 2024, Novembar
Anonim
Image
Image

Otkrivanje muzičkih nota iz audio signala je teško izvesti posebno na Arduinu zbog ograničene memorije i procesorske snage. Općenito, nota nije čisti sinusni val koji otežava otkrivanje. Ako uzmemo frekvencijsku transformaciju različitih muzičkih instrumenata, ona može sadržavati više harmonika na osnovu note koja se svira. Svaki instrument ima svoju kombinaciju različitih harmonika. U ovom kodu pokušao sam napraviti program koji može pokriti što je moguće 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 klavijatura, pa čak i zvuk vokala. Tačnost detekcije varira od instrumenta do instrumenta. Za neki instrument (tj. Klavir) u ograničenom rasponu (200-500Hz) tačan je, dok za neki instrument ima nisku tač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.

Supplies

- 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 toku:

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 se koristi za primjenu Hannove funkcije prozora, kao i za izračunavanje amplitude/RMS. Ovaj kod također vrši grubo nuliranje oduzimanjem 500 od vrijednosti analognog čitanja. Ova vrijednost se 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 otkriti 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 konverzije float u intMicroseconds (195); // zasnovano na radnom frekvencijskom opsegu}

2. FFT:

Kada su podaci spremni, FFT se izvodi pomoću EasyFFT -a. Ova funkcija EasyFFT modificirana je da popravi FFT za 128 uzoraka. Kôd je također izmijenjen 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 odnosu na originalnu funkciju EasyFFT.

Kada se FFT završi, kod vraća prvih 5 najdominantnijih vrhova frekvencije za daljnju analizu. Ove frekvencije su raspoređene po opadajućem amplitudnom redoslijedu.

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

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

NoteV vrijednosti niza 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čunavanja note za svaku frekvenciju može se dogoditi da postoji više frekvencija koje postoje što ukazuje na istu notu. Da biste imali točan izlazni kod, također se razmatraju ponavljanja. Kôd zbraja sve vrijednosti frekvencije na osnovu redoslijeda amplituda i ponavljanja te naglašava notu maksimalnom amplitudom.

Korak 2: Aplikacija

Korištenje koda je jednostavno, međutim, postoji 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 donje točke.

1. Dodjela pinova:

Na osnovu priloženog dodjeljivanja pin -a potrebno je izmijeniti. Za svoj eksperiment, zadržao sam ga na analognom pinu 7, void setup () {Serial.begin (250000); Mic_pin = A7; }

2. Osetljivost mikrofona:

Potrebno je promijeniti osjetljivost mikrofona, 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 ni premalen, a ni zbog velike amplitude ne odsiječe.

3. Prag amplitude:

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

if (sum2-sum1> 5) {

..

u gornjem kodu, sum2 daje RMS vrijednost, dok zbir 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 će prema zadanim postavkama ispisati otkrivenu bilješku. međutim, ako bilješku namjeravate upotrijebiti 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. maksimalna frekvencija je ograničena frekvencijom uzorkovanja. pa se možete poigrati ispod vrijednosti kašnjenja kako biste postigli optimalan učinak. u donjem odlogu koda od 195 mikrosekundi. koje se mogu prilagoditi kako bi se postigao optimalan učinak. To će utjecati na ukupno vrijeme izvođenja.

{a = analogRead (Mic_pin) -500; // gruba nulti pomak

zbir1 = zbir1+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 konverzije float u intMicroseconds (195); // zasnovano na radnom frekvencijskom opsegu}

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

Mjere predostrožnosti:

  • 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 kod može dobro funkcionirati za jedan instrument/vokal, a loše za drugi. Precizno otkrivanje u stvarnom vremenu nije moguće zbog računalnih ograničenja.

Korak 3: Ljeto

Otkrivanje bilješki je računarski intenzivan posao, dobivanje rezultata u stvarnom vremenu je vrlo teško, posebno na Arduinu. Ovaj kôd može dati oko 6,6 uzoraka /sekundi (za dodano kašnjenje od 195 mikrosekundi). ovaj kod 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 muziku. 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 muzičkih akorda. pa ostanite s nama.

Preporučuje se: