Tartalomjegyzék:

Arduino Music Notes Detector: 3 lépés
Arduino Music Notes Detector: 3 lépés

Videó: Arduino Music Notes Detector: 3 lépés

Videó: Arduino Music Notes Detector: 3 lépés
Videó: Control Position and Speed of Stepper motor with L298N module using Arduino 2024, November
Anonim
Image
Image

A hangjegyek felismerése az audiojelből nehezen kivitelezhető, különösen az Arduino esetében a korlátozott memória és a feldolgozási teljesítmény miatt. Általában a hang nem tiszta szinuszhullám, ami megnehezíti az észlelést. Ha a különböző hangszerek frekvenciaátalakítását vesszük, akkor a felcsendülő hang alapján több felharmonikust is tartalmazhat. Minden hangszer saját kombinációját tartalmazza a különböző harmonikusoknak. Ebben a kódban olyan programot próbáltam készíteni, amely a lehető legtöbb hangszert képes lefedni. Hivatkozhat a csatolt videóra, amelyben megpróbáltam tesztelni a különféle hangszereket, a billentyűzet által generált különféle hangokat és még az ének hangját is. Az észlelés pontossága műszerenként változik. Néhány hangszer (azaz zongora) esetén korlátozott tartományban (200-500 Hz) pontos, míg egyes hangszereknél alacsony pontosságú (azaz szájharmonika).

Ez a kód egy korábban kifejlesztett EasyFFT kódot használ.

A kód bemutatását a fenti videó mutatja, különféle hangszerhangokkal és énekkel.

Kellékek

- Arduino Nano/Uno vagy újabb

- Mikrofon modul az Arduino számára

1. lépés: A megjegyzések észlelésének algoritmusa

Amint az előző lépésben említettük, az észlelés nehéz, mivel több frekvencia van jelen az audio mintákban.

A program a következő folyamatokban működik:

1. Adatgyűjtés:

- ez a szakasz 128 mintát vesz az audio adatokból, a két minta közötti elválasztást (mintavételi gyakoriság) az érdeklődési gyakoriságtól függően. Ebben az esetben két minta közötti távolságot használunk a Hann ablak funkció és az amplitúdó/RMS kiszámításához. Ez a kód durva nullázást is végez azzal, hogy az analóg olvasott értékből kivon 500 -at. Ez az érték szükség esetén megváltoztatható. Tipikus esetben ez az érték jól működik. Továbbá némi késleltetést kell hozzáadni ahhoz, hogy a mintavételi frekvencia körülbelül 1200 Hz legyen. 1200 Hz mintavételi frekvencia esetén maximum 600 Hz frekvencia észlelhető.

for (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // durva nulla eltolás összege1 = összeg1+a; // átlagértékig sum2 = összeg2+a*a; // RMS értékre a = a*(sin (i*3,14/128)*sin (i*3,14/128)); // Hann ablak itt: = 4*a; // skálázás float int int konverziós késleltetéshezMikroszekundum (195); // működési frekvenciatartomány alapján}

2. FFT:

Amint az adatok készen állnak, az FFT az EasyFFT használatával történik. Ez az EasyFFT funkció 128 minta FFT rögzítésére lett módosítva. A kódot a memóriafogyasztás csökkentése érdekében is módosítják. Az eredeti EasyFFT funkció legfeljebb 1028 mintát tartalmaz (a kompatibilis táblával), míg csak 128 mintára van szükségünk. ez a kód körülbelül 20% -kal csökkenti a memóriafogyasztást az eredeti EasyFFT funkcióhoz képest.

Az FFT elvégzése után a kód visszaadja az első 5 domináns frekvenciacsúcsot további elemzéshez. Ez a frekvencia az amplitúdó csökkenő sorrendjében van elrendezve.

3. Minden csúcs esetén a kód észleli a hozzá kapcsolódó lehetséges jegyzeteket. ez a kód csak 1200 Hz -ig terjed. Nem szükséges, hogy ugyanaz legyen a jegyzet, mint a maximális amplitúdójú frekvencia.

Minden frekvencia 0 és 255 között van leképezve, itt az első oktáv észlelhető, például 65,4–130,8 egy oktávot jelent, 130,8–261,6 Hz pedig egy másikat. Minden oktáv esetében a frekvenciák 0 és 255 között vannak leképezve.

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);}

A NoteV tömb értékeit használjuk a jegyzet hozzárendeléséhez az észlelt frekvenciákhoz.

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

4. Miután kiszámította a hangot minden frekvenciára, előfordulhat, hogy több olyan frekvencia létezik, amelyek ugyanazt a hangot sugallják. Ahhoz, hogy pontos kimeneti kód legyen, figyelembe veszi az ismétléseket is. A kód összeadja az összes frekvenciaértéket az amplitúdó sorrendje és az ismétlések alapján, és maximális amplitúdóval csúcsosítja fel a hangot.

2. lépés: Alkalmazás

A kód használata egyszerű, azonban számos korlátozás is van, amelyeket szem előtt kell tartani. A kód másolható, mivel a jegyzetek észlelésére szolgál. Használatakor figyelembe kell venni az alábbi pontokat.

1. Tű hozzárendelés:

A csatolt Pin -hozzárendelés alapján módosítani kell. Kísérletemhez a 7 -es analóg érintkezőhöz tartottam, void setup () {Serial.begin (250000); Mic_pin = A7; }

2. Mikrofon érzékenység:

A mikrofon érzékenységét módosítani kell, így a hullámforma jó amplitúdóval generálható. A mikrofonmodul többnyire érzékenységi beállítással rendelkezik. megfelelő érzékenységet kell kiválasztani, hogy a jel ne legyen túl kicsi, és a nagyobb amplitúdó miatt le ne váljon.

3. Amplitúdó küszöb:

Ez a kód csak akkor aktiválódik, ha a jel amplitúdója elég magas. ezt a beállítást a felhasználónak manuálisan kell megadnia. ez az érték függ a mikrofon érzékenységétől és az alkalmazástól.

ha (összeg2-összeg1> 5) {

..

a fenti kódban az összeg2 az RMS értéket adja meg, míg az összeg 1 az átlagértéket. tehát e két érték közötti különbség megadja a hangjel amplitúdóját. az én esetemben megfelelően működik 5 körüli amplitúdó értékkel.

4. Alapértelmezés szerint ez a kód kinyomtatja az észlelt jegyzetet. ha azonban a jegyzetet valamilyen más célra tervezi használni, akkor a közvetlenül hozzárendelt számot kell használni. például C = 0; C#= 1, D = 2, D#= 3 és tovább.

5. Ha a műszer frekvenciája magasabb, a kód hamis kimenetet adhat. a maximális frekvenciát a mintavételi frekvencia korlátozza. így az optimális kimenet elérése érdekében játszhat a késleltetett értékek alatt. a kód alatti késleltetés 195 mikroszekundum. amelyet módosítani lehet az optimális kimenet elérése érdekében. Ez befolyásolja a teljes végrehajtási időt.

{a = analóg olvasat (Mic_pin) -500; // durva nulla eltolás

összeg1 = összeg1+a; // átlagértékig sum2 = összeg2+a*a; // RMS értékre a = a*(sin (i*3,14/128)*sin (i*3,14/128)); // Hann ablak itt: = 4*a; // skálázás float int int konverziós késleltetéshezMikroszekundum (195); // működési frekvenciatartomány alapján}

6. ez a kód csak 2000Hz -es frekvenciáig működik. a mintavételek közötti késleltetés kiküszöbölésével körülbelül 3-4 kHz mintavételi frekvencia érhető el.

Óvintézkedések:

  • Amint azt az EasyFFT oktatóanyagban említettük, az FFT hatalmas memóriát emészt fel az Arduino -ról. Tehát ha olyan programja van, amely bizonyos értékeket tárol, akkor ajánlott nagyobb memóriájú táblát használni.
  • Ez a kód jól működhet az egyik hangszer/énekes és rossz a másik számára. Valós idejű A pontos észlelés nem lehetséges a számítási korlátok miatt.

3. lépés: Nyár

A jegyzetfelismerés számításigényes munka, a valós idejű kimenet megszerzése nagyon nehéz, különösen az Arduino esetében. Ez a kód körülbelül 6,6 mintát adhat másodpercenként (195 mikroszekundumos késleltetéssel). ez a kód jól működik a zongorával és néhány más hangszerrel.

Remélem, hogy ez a kód és oktatóanyag hasznos lesz a zenével kapcsolatos projektben. bármilyen kétség vagy javaslat esetén nyugodtan írjon megjegyzést vagy üzenetet.

A közelgő oktatóanyagban ezt a kódot módosítom a zenei akkordok észlelésére. szóval maradj velünk.

Ajánlott: