Obsah:

Detektor poznámok k hudbe Arduino: 3 kroky
Detektor poznámok k hudbe Arduino: 3 kroky

Video: Detektor poznámok k hudbe Arduino: 3 kroky

Video: Detektor poznámok k hudbe Arduino: 3 kroky
Video: Arduino Air Piano MIDI controller - More testing 2024, November
Anonim
Image
Image

Detekciu hudobných poznámok zo zvukového signálu je ťažké vykonať najmä na Arduine kvôli obmedzenej pamäti a výkonu spracovania. Vo všeobecnosti poznámka nie je čistá sínusová vlna, ktorá sťažuje detekciu. Ak vezmeme frekvenčnú transformáciu rôznych hudobných nástrojov, môže obsahovať viac harmonických podľa založenej noty. Každý nástroj má svoju vlastnú kombináciu rôznych harmonických. V tomto kóde som sa pokúsil vytvoriť program, ktorý dokáže pokryť čo najviac nástrojov. Môžete si pozrieť priložené video, v ktorom som sa pokúsil otestovať rôzne typy nástrojov, rôzne typy tónov generovaných klávesnicou a dokonca aj zvuk vokálov. Presnosť detekcie sa líši prístroj od nástroja. U niektorých nástrojov (t.j. klavíra) v obmedzenom rozsahu (200-500 Hz) je presný, zatiaľ čo u niektorých nástrojov má nízku presnosť (t. J. Harmonika).

Tento kód využíva predtým vyvinutý kód FFT s názvom EasyFFT.

Ukážka kódu je vo vyššie uvedenom videu zobrazená s rôznymi druhmi zvuku nástrojov i vokálov.

Zásoby

- Arduino Nano/Uno alebo novší

- Mikrofónny modul pre Arduino

Krok 1: Algoritmus pre detekciu poznámok

Ako bolo uvedené v predchádzajúcom kroku, detekcia je náročná z dôvodu prítomnosti viacerých frekvencií vo zvukových ukážkach.

Program funguje v nasledujúcom toku:

1. Zber údajov:

- táto časť odoberá 128 vzoriek zo zvukových údajov, pričom oddelenie dvoch vzoriek (vzorkovacia frekvencia) závisí od požadovanej frekvencie. V tomto prípade používame medzery medzi dvoma vzorkami, ktoré sa používajú na aplikáciu funkcie Hannovho okna, ako aj na výpočet amplitúdy/RMS. Tento kód tiež robí hrubé nulovanie odčítaním 500 od analógovej hodnoty. Túto hodnotu je možné v prípade potreby zmeniť. V typickom prípade tieto hodnoty fungujú dobre. Ďalej je potrebné pridať určité oneskorenie, aby mala vzorkovaciu frekvenciu okolo 1200 Hz. v prípade 1 200 Hz je možné detekovať vzorkovaciu frekvenciu maximálne 600 Hz.

pre (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // hrubý nulový posun súčet1 = súčet1+a; // na priemernú hodnotu sum2 = sum2+a*a; // na hodnotu RMS a = a*(sin (i*3,14/128)*sin (i*3,14/128)); // Hannovo okno v = 4*a; // škálovanie pre oneskorenie prevodu float na intMicroseconds (195); // na základe prevádzkového frekvenčného rozsahu}

2. FFT:

Akonáhle sú údaje pripravené, FFT sa vykoná pomocou EasyFFT. Táto funkcia EasyFFT je upravená tak, aby opravovala FFT pre 128 vzoriek. Kód je tiež upravený tak, aby sa znížila spotreba pamäte. Pôvodná funkcia EasyFFT bola navrhnutá tak, aby mala až 1028 vzoriek (s kompatibilnou doskou), pričom potrebujeme iba 128 vzoriek. tento kód znižuje spotrebu pamäte o približne 20% v porovnaní s pôvodnou funkciou EasyFFT.

Akonáhle je FFT hotový, kód vráti prvých 5 najdominantnejších frekvenčných špičiek na ďalšiu analýzu. Táto frekvencia je usporiadaná zostupne podľa amplitúdy.

3. Pri každom vrchole kód detekuje možné poznámky, ktoré sú s ním spojené. tento kód skenuje iba do 1 200 Hz. Nie je potrebné mať na pamäti rovnakú frekvenciu ako pri maximálnej amplitúde.

Všetky frekvencie sú mapované od 0 do 255, tu je detekovaná prvá oktáva, napríklad 65,4 Hz až 130,8 predstavuje jednu oktávu, 130,8 Hz až 261,6 Hz predstavuje druhú. Pre každú oktávu sú frekvencie mapované od 0 do 255. Tu mapovanie začína 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);}

Hodnoty poľa NoteV sa používajú na priradenie poznámky k detekovaným frekvenciám.

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

4. Po výpočte noty pre každú frekvenciu sa môže stať, že existuje niekoľko frekvencií, ktoré naznačujú rovnakú notu. Ak chcete mať presný výstupný kód, zvažuje sa aj opakovanie. Kód sčíta všetky hodnoty frekvencie na základe poradia amplitúdy a opakovaní a vrcholí notu s maximálnou amplitúdou.

Krok 2: Aplikácia

Používanie kódu je jednoduché, existuje však aj niekoľko obmedzení, ktoré je potrebné mať na pamäti. Kód je možné skopírovať, pretože sa používa na detekciu poznámok. Pri jeho použití je potrebné vziať do úvahy nasledujúce body.

1. Priradenie pinov:

Na základe priloženého PIN priradenia je potrebné upraviť. Pre svoj experiment som ho ponechal na analógovom pine 7, void setup () {Serial.begin (250000); Mic_pin = A7; }

2. Citlivosť mikrofónu:

Citlivosť mikrofónu je potrebné upraviť, aby bolo možné tvar vlny generovať s dobrou amplitúdou. Modul mikrofónu je väčšinou dodávaný s nastavením citlivosti. je potrebné zvoliť vhodnú citlivosť tak, aby signál nebol ani príliš malý, ani sa nevypínal kvôli vyššej amplitúde.

3. Prah amplitúdy:

Tento kód sa aktivuje iba vtedy, ak je amplitúda signálu dostatočne vysoká. toto nastavenie musí užívateľ nastaviť ručne. táto hodnota závisí od citlivosti mikrofónu a aplikácie.

if (sum2-sum11> 5) {

..

vo vyššie uvedenom kóde sum2 dáva hodnotu RMS, zatiaľ čo súčet 1 dáva priemernú hodnotu. takže rozdiel medzi týmito dvoma hodnotami udáva amplitúdu zvukového signálu. v mojom prípade funguje správne s hodnotou amplitúdy okolo 5.

4. V predvolenom nastavení tento kód vytlačí zistenú poznámku. ak však plánujete použiť poznámku na iný účel, malo by sa použiť priamo priradené číslo. napríklad C = 0; C#= 1, D = 2, D#= 3 a ďalej.

5. Ak má prístroj vyššiu frekvenciu, kód môže poskytovať falošný výstup. maximálna frekvencia je obmedzená vzorkovacou frekvenciou. takže sa môžete pohrať pod hodnotami oneskorenia, aby ste dosiahli optimálny výstup. v nižšie uvedenom kódovom oneskorení 195 mikrosekúnd. ktoré je možné vyladiť, aby sa dosiahol optimálny výkon. To ovplyvní celkový čas vykonania.

{a = analogRead (Mic_pin) -500; // hrubý posun nuly

súčet1 = súčet1+a; // na priemernú hodnotu sum2 = sum2+a*a; // na hodnotu RMS a = a*(sin (i*3,14/128)*sin (i*3,14/128)); // Hannovo okno v = 4*a; // škálovanie pre oneskorenie konverzie float to intMicroseconds (195); // na základe prevádzkového frekvenčného rozsahu}

6. tento kód bude fungovať iba do frekvencie 2000 Hz. odstránením oneskorenia medzi vzorkovaním je možné získať približne 3-4 kHz vzorkovacích frekvencií.

Opatrenia:

  • Ako je uvedené v návode EasyFFT, FFT zaberá obrovské množstvo pamäte Arduino. Ak teda máte program, ktorý potrebuje uložiť niektoré hodnoty, odporúča sa použiť dosku s vyššou pamäťou.
  • Tento kód môže fungovať dobre na jeden nástroj/speváka a na iný zle. Presná detekcia v reálnom čase nie je možná z dôvodu výpočtových obmedzení.

Krok 3: Letný

Detekcia poznámok je výpočtovo náročná práca, obzvlášť v Arduine je získanie výstupu v reálnom čase veľmi ťažké. Tento kód môže poskytnúť približne 6,6 vzoriek /sekundu (pre 195 mikrosekúnd je pridané oneskorenie). tento kód funguje dobre s klavírom a niektorými ďalšími nástrojmi.

Dúfam, že tento kód a návod budú nápomocné vo vašom projekte týkajúcom sa hudby. v prípade akýchkoľvek pochybností alebo návrhov neváhajte komentovať alebo napísať správu.

V nadchádzajúcom návode upravím tento kód na detekciu hudobného akordu. tak zostaňte naladení.

Odporúča: