Obsah:

Detektor hudebních poznámek Arduino: 3 kroky
Detektor hudebních poznámek Arduino: 3 kroky

Video: Detektor hudebních poznámek Arduino: 3 kroky

Video: Detektor hudebních poznámek Arduino: 3 kroky
Video: ELF/EMBARC Bronchiectasis conference 2023 with subtitles 2024, Listopad
Anonim
Image
Image

Zjištění hudebních poznámek ze zvukového signálu je obtížné, zejména na Arduinu, kvůli omezené paměti a výpočetnímu výkonu. Poznámka obecně není čistá sinusová vlna, která ztěžuje detekci. Pokud vezmeme frekvenční transformaci různých hudebních nástrojů, může obsahovat více harmonických na základě noty, na kterou se hraje. Každý nástroj má svou vlastní kombinaci různých harmonických. V tomto kódu jsem se pokusil vytvořit program, který dokáže pokrýt co nejvíce nástrojů. Můžete se podívat na přiložené video, ve kterém jsem zkoušel testovat různé typy nástrojů, různé typy tónů generovaných klávesnicí a dokonce i zvuk vokálu. Přesnost detekce se liší nástroj od nástroje. U některých nástrojů (tj. Klavíru) v omezeném rozsahu (200-500 Hz) je přesný, zatímco u některých nástrojů má nízkou přesnost (tj. Harmonika).

Tento kód využívá dříve vyvinutý kód FFT s názvem EasyFFT.

Demonstrace kódu je ve výše uvedeném videu zobrazena s různými druhy zvuku nástroje i vokálu.

Zásoby

- Arduino Nano/Uno nebo vyšší

- Mikrofonní modul pro Arduino

Krok 1: Algoritmus pro detekci poznámek

Jak již bylo zmíněno v předchozím kroku, detekce je obtížná kvůli přítomnosti více frekvencí ve zvukových vzorcích.

Program funguje v následujícím toku:

1. Sběr dat:

- tato část přebírá 128 vzorků ze zvukových dat, přičemž oddělení dvou vzorků (vzorkovací frekvence) závisí na požadované frekvenci. V tomto případě používáme mezery mezi dvěma vzorky, které se používají k aplikaci Hannovy funkce okna a výpočtu amplitudy/RMS. Tento kód také provádí hrubé nulování odečtením 500 od hodnoty analogového čtení. Tuto hodnotu lze v případě potřeby změnit. Pro typický případ tyto hodnoty fungují dobře. Dále je třeba přidat určité zpoždění, aby měla vzorkovací frekvenci kolem 1200 Hz. v případě vzorkovací frekvence 1200 Hz lze detekovat max. frekvenci 600 Hz.

pro (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // hrubý nulový posun součet1 = součet1+a; // na průměrnou 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álování pro konverzi float na int delayMicroseconds (195); // na základě provozního frekvenčního rozsahu}

2. FFT:

Jakmile jsou data připravena, provede se FFT pomocí EasyFFT. Tato funkce EasyFFT je upravena tak, aby opravila FFT pro 128 vzorků. Kód je také upraven, aby se snížila spotřeba paměti. Původní funkce EasyFFT byla navržena tak, aby měla až 1028 vzorků (s kompatibilní deskou), zatímco my potřebujeme pouze 128 vzorků. tento kód snižuje spotřebu paměti přibližně o 20% ve srovnání s původní funkcí EasyFFT.

Jakmile je FFT hotové, kód vrátí 5 nejdominantnějších frekvenčních špiček pro další analýzu. Tato frekvence je uspořádána sestupně podle amplitudy.

3. Pro každý vrchol kód detekuje možné poznámky, které jsou s ním spojeny. tento kód snímá pouze do 1 200 Hz. Není nutné mít stejnou notu jako frekvence s maximální amplitudou.

Všechny frekvence jsou mapovány mezi 0 až 255, zde je detekována první oktáva, například 65,4 Hz až 130,8 představuje jednu oktávu, 130,8 Hz až 261,6 Hz představuje druhou. Pro každou oktávu jsou frekvence mapovány od 0 do 255. zde mapování 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 pole NoteV se používají k přiřazení poznámky k detekovaným frekvencím.

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

4. Po výpočtu noty pro každou frekvenci může nastat situace, že existuje více frekvencí, což naznačuje stejnou notu. Chcete -li mít přesný výstupní kód, zvažuje také opakování. Kód sečte všechny hodnoty frekvence na základě pořadí amplitud a opakování a vrcholí notu s maximální amplitudou.

Krok 2: Aplikace

Používání kódu je přímočaré, ale existuje také několik omezení, která je třeba mít na paměti. Kód lze zkopírovat, protože se používá k detekci poznámek. Při používání je třeba vzít v úvahu následující body.

1. Přiřazení pinů:

Na základě připojeného PINu je třeba upravit přiřazení. Pro svůj experiment jsem to nechal na analogovém pinu 7, neplatné nastavení () {Serial.begin (250000); Mic_pin = A7; }

2. Citlivost mikrofonu:

Je třeba upravit citlivost mikrofonu, aby bylo možné generovat vlnovou křivku s dobrou amplitudou. Modul mikrofonu je většinou dodáván s nastavením citlivosti. je třeba zvolit vhodnou citlivost tak, aby signál nebyl ani příliš malý, ani aby nevypadával kvůli vyšší amplitudě.

3. Práh amplitudy:

Tento kód se aktivuje, pouze pokud je amplituda signálu dostatečně vysoká. toto nastavení musí uživatel nastavit ručně. tato hodnota závisí na citlivosti mikrofonu i na aplikaci.

if (součet2-součet1> 5) {

..

ve výše uvedeném kódu sum2 dává hodnotu RMS, zatímco součet 1 udává střední hodnotu. takže rozdíl mezi těmito dvěma hodnotami udává amplitudu zvukového signálu. v mém případě funguje správně s hodnotou amplitudy kolem 5.

4. Ve výchozím nastavení tento kód vytiskne zjištěnou poznámku. pokud však plánujete použít poznámku k jinému účelu, mělo by být použito přímo přiřazené číslo. například C = 0; C#= 1, D = 2, D#= 3 a dále.

5. Pokud má nástroj vyšší frekvenci, kód může poskytovat falešný výstup. maximální frekvence je omezena vzorkovací frekvencí. takže můžete hrát pod hodnotami zpoždění, abyste získali optimální výstup. v níže uvedeném kódu zpoždění 195 mikrosekund. které lze upravit tak, aby bylo dosaženo optimálního výkonu. To ovlivní celkovou dobu provádění.

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

součet1 = součet1+a; // na průměrnou 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álování pro konverzi float na int delayMicroseconds (195); // na základě provozního frekvenčního rozsahu}

6. tento kód bude fungovat pouze do frekvence 2000 Hz. odstraněním zpoždění mezi vzorkováním lze získat přibližně 3–4 kHz vzorkovacích frekvencí.

Opatření:

  • Jak je uvedeno v tutoriálu EasyFFT, FFT pohltí obrovské množství paměti Arduina. Pokud tedy máte program, který potřebuje uložit nějaké hodnoty, doporučujeme použít desku s vyšší pamětí.
  • Tento kód může fungovat dobře pro jeden nástroj/zpěváka a pro jiný špatně. Přesná detekce v reálném čase není možná z důvodu výpočetních omezení.

Krok 3: Letní

Detekce poznámek je výpočetně náročná práce, získání výstupu v reálném čase je velmi obtížné, zejména na Arduinu. Tento kód může poskytnout přibližně 6,6 vzorků /sekundu (přidáno zpoždění 195 mikrosekund). tento kód funguje dobře s klavírem a některými dalšími nástroji.

Doufám, že tento kód a tutoriál budou užitečné ve vašem projektu týkajícím se hudby. v případě jakýchkoli pochybností nebo návrhů neváhejte napsat komentář nebo zprávu.

V nadcházejícím tutoriálu upravím tento kód pro detekci hudebních akordů. tak zůstaňte naladěni.

Doporučuje: