Kazalo:

Detektor glasbenih not: 3 koraki
Detektor glasbenih not: 3 koraki

Video: Detektor glasbenih not: 3 koraki

Video: Detektor glasbenih not: 3 koraki
Video: Oxxxymiron - Переплетено (2016) 2024, November
Anonim
Image
Image

Presenetite svoje prijatelje in družino s tem projektom, ki zazna noto, ki jo igra inštrument. Ta projekt bo prikazal približno frekvenco in glasbeno noto, ki se igra na elektronski klaviaturi, aplikaciji za klavir ali katerem koli drugem instrumentu.

Podrobnosti

Za ta projekt se analogni izhod iz detektorja zvočnega modula pošlje na analogni vhod A0 Arduino Uno. Analogni signal se vzorči in kvantizira (digitalizira). Koda za samodejno korelacijo, uteženje in uglaševanje se uporablja za iskanje osnovne frekvence z uporabo prvih treh obdobij. Približno osnovno frekvenco nato primerjamo s frekvencami v razponu oktav 3, 4 in 5, da določimo najbližjo frekvenco glasbene note. Nazadnje se na zaslon natisne uganka za najbližjo frekvenco.

Opomba: Ta navodila se osredotočajo le na to, kako zgraditi projekt. Za več informacij o podrobnostih in utemeljitvah zasnove obiščite to povezavo: Več informacij

Zaloge

  • (1) Arduino Uno (ali Genuino Uno)
  • (1) Združljiv modul za zaznavanje zvoka z visoko občutljivostjo mikrofona DEVMO
  • (1) Lemilna plošča brez spajkanja
  • (1) Kabel USB-A do B
  • Mostične žice
  • Glasbeni vir (klavir, klaviatura ali paino aplikacija z zvočniki)
  • (1) Računalnik ali prenosni računalnik

1. korak: Zgradite strojno opremo za detektor glasbenih not

Namestite detektor glasbenih not
Namestite detektor glasbenih not

S pomočjo Arduino Uno povezovalne žice, lemljena plošča in DEVMO mikrofonski senzor za visoko občutljivost modula za zaznavanje zvoka (ali podobnega) oblikujejo vezje, prikazano na tej sliki

2. korak: Programirajte detektor glasbenih not

V Arduino IDE dodajte naslednjo kodo.

gistfile1.txt

/*
Ime datoteke/skice: MusicalNoteDetector
Različica: v1.0 Ustvarjeno 7. junija 2020
Originalni avtor: Clyde A. Lettsome, PhD, PE, MEM
Opis: Ta koda/skica prikazuje približno frekvenco in glasbeno noto, ki se predvaja na elektronski tipkovnici ali aplikaciji za klavir. Za ta projekt je analogni izhod iz
Detektor zvočnega modula se pošlje na analogni vhod A0 Arduino Uno. Analogni signal se vzorči in kvantizira (digitalizira). Koda za avtokorelacijo, uteževanje in uglaševanje je navajena
poiščite osnovno frekvenco z uporabo prvih treh obdobij. Približno osnovno frekvenco nato primerjamo s frekvencami v oktavah 3, 4 in 5, da določimo najbližji muzikal
notna frekvenca. Nazadnje se na zaslon natisne uganka za najbližjo frekvenco.
Licenca: Ta program je brezplačna programska oprema; lahko ga distribuirate in/ali spremenite pod pogoji GNU Splošne javne licence (GPL) različice 3 ali pozneje
različico po vaši izbiri, ki jo je objavila Fundacija za brezplačno programsko opremo.
Opombe: Avtorske pravice (c) 2020 C. A. Lettsome Services, LLC
Za več informacij obiščite
*/
#define SAMPLES 128 // Max 128 za Arduino Uno.
#define SAMPLING_FREQUENCY 2048 // Fs = Na podlagi Nyquista mora biti 2 -krat najvišja pričakovana frekvenca.
#define OFFSETSAMPLES 40 // se uporablja za kalabriranje
#define TUNER -3 // Prilagodite, dokler C3 ne znaša 130,50
obdobje vzorčenja float
nepodpisane dolge mikrosekunde;
int X [VZORCI]; // ustvarimo vektor velikosti VZORCI, ki bodo vsebovali resnične vrednosti
float autoCorr [VZORCI]; // ustvarimo vektor velikosti VZORCI, ki bodo imeli namišljene vrednosti
float shranjenoOpombaFreq [12] = {130,81, 138,59, 146,83, 155,56, 164,81, 174,61, 185, 196, 207,65, 220, 233,08, 246,94};
int sumOffSet = 0;
int offSet [OFFSETSAMPLES]; // ustvari vektor odmika
int avgOffSet; // ustvari vektor odmika
int i, k, periodEnd, periodBegin, period, adjuster, noteLocation, octaveRange;
float maxValue, minValue;
dolga vsota;
int thresh = 0;
int numOfCycles = 0;
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, skupaj;
bajt state_machine = 0;
int vzorciPerPeriod = 0;
void setup ()
{
Serial.begin (115200); // 115200 hitrost prenosa za serijski monitor
}
void loop ()
{
//*****************************************************************
// Oddelek za umerjanje
//*****************************************************************
Serial.println ("Kalabriranje. Med kalibracijo ne predvajajte nobenih not.");
for (i = 0; i <OFFSETSAMPLES; i ++)
{
offSet = analogRead (0); // Odčita vrednost z analognega zatiča 0 (A0), jo kvantizira in shrani kot pravi izraz.
//Serial.println(offSet); // s tem nastavite modul za zaznavanje zvoka na približno polovico ali 512, ko se ne predvaja zvok.
sumOffSet = sumOffSet + offSet ;
}
vzorciPerPeriod = 0;
maxValue = 0;
//*****************************************************************
// Pripravite se na sprejem vnosa iz A0
//*****************************************************************
avgOffSet = okroglo (sumOffSet / OFFSETSAMPLES);
Serial.println ("Odštevanje.");
zamuda (1000); // zaustavitev za 1 sekundo
Serial.println ("3");
zamuda (1000); // zaustavitev za 1 sekundo
Serial.println ("2");
zamuda (1000); // premor za 1
Serial.println ("1");
zamuda (1000); // zaustavitev za 1 sekundo
Serial.println ("Predvajaj svojo noto!");
zamuda (250); // za premor za 1/4 sekunde za reakcijski čas
//*****************************************************************
// Zberemo vzorce vzorcev iz A0 z vzorčnim obdobjem vzorčnega obdobja
//*****************************************************************
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Obdobje v mikrosekundah
za (i = 0; i <VZORCI; i ++)
{
mikrosekunde = mikros (); // Vrne število mikrosekund, odkar je plošča Arduino začela izvajati trenutni skript.
X = analogRead (0); // Odčita vrednost z analognega zatiča 0 (A0), jo kvantizira in shrani kot pravi izraz.
/ *preostali čakalni čas med vzorci, če je potrebno, v sekundah */
medtem ko (mikro () <(mikrosekunde + (obdobje vzorčenja * 1000000)))
{
// ne delajte ničesar samo počakajte
}
}
//*****************************************************************
// Funkcija avtokorelacije
//*****************************************************************
for (i = 0; i <VZORCI; i ++) // i = zamuda
{
vsota = 0;
for (k = 0; k <VZORCI - i; k ++) // Ujemite signal z zakasnjenim signalom
{
vsota = vsota + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] je signal in X [k+i] je zakasnjena različica
}
autoCorr = vsota / VZORCI;
// Prvi stroj za zaznavanje vrha
če (state_machine == 0 && i == 0)
{
thresh = autoCorr * 0,5;
stanje_stroja = 1;
}
sicer če (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, poiščite 1 obdobje za uporabo prvega cikla
{
maxValue = autoCorr ;
}
sicer če (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodBegin = i-1;
stanje_stroja = 2;
število ciklov = 1;
vzorciPerPeriod = (periodBegin - 0);
obdobje = vzorciPerPeriod;
nastavitelj = TUNER+(50,04 * eksp. (-0,102 * vzorci na obdobje));
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-nastavitelj; // f = fs/N
}
sicer če (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, poiščite 2 obdobja za 1. in 2. cikel
{
maxValue = autoCorr ;
}
sicer če (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
stanje_stroja = 3;
število ciklov = 2;
vzorciPerPeriod = (periodEnd - 0);
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-nastavitelj; // f = (2*fs)/(2*N)
maxValue = 0;
}
sicer če (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, poiščite 3 obdobja za 1., 2. in 3. cikel
{
maxValue = autoCorr ;
}
sicer če (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
stanje_stroja = 4;
število ciklov = 3;
vzorciPerPeriod = (periodEnd - 0);
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-nastavitelj; // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// Analiza rezultatov
//*****************************************************************
če (vzorčniPeriod == 0)
{
Serial.println ("Hmm….. Nisem prepričan. Me poskušate prevarati?");
}
drugače
{
// pripravimo tehtalno funkcijo
skupaj = 0;
if (signalFrequency! = 0)
{
skupaj = 1;
}
if (signalFrequency2! = 0)
{
skupaj = skupaj + 2;
}
if (signalFrequency3! = 0)
{
skupaj = skupaj + 3;
}
// izračunajte frekvenco s funkcijo ponderiranja
signalFrequencyGuess = ((1/skupaj) * signalFrequency) + ((2/skupaj) * signalFrequency2) + ((3/skupaj) * signalFrequency3); // poiščite tehtano frekvenco
Serial.print ("Opomba, ki ste jo odigrali, je približno");
Serial.print (signalFrequencyGuess); // Natisni ugibanje o frekvenci.
Serial.println ("Hz.");
// poiščite oktavno območje na podlagi ugibanja
oktavaRange = 3;
medtem ko (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7))
{
za (i = 0; i <12; i ++)
{
shranjenoNoteFreq = 2 * shranjenoNoteFreq ;
}
octaveRange ++;
}
// Poiščite najbližjo opombo
minVrednost = 10000000;
noteLocation = 0;
za (i = 0; i <12; i ++)
{
if (minValue> abs (signalFrequencyGuess-storedNoteFreq ))
{
minValue = abs (signalFrequencyGuess-storedNoteFreq );
noteLocation = i;
}
}
// Natisnite beležko
Serial.print ("Mislim, da ste igrali");
če (noteLocation == 0)
{
Serial.print ("C");
}
sicer če (noteLocation == 1)
{
Serial.print ("C#");
}
sicer če (noteLocation == 2)
{
Serial.print ("D");
}
sicer če (noteLocation == 3)
{
Serial.print ("D#");
}
sicer če (noteLocation == 4)
{
Serial.print ("E");
}
sicer če (noteLocation == 5)
{
Serial.print ("F");
}
sicer če (noteLocation == 6)
{
Serial.print ("F#");
}
sicer če (noteLocation == 7)
{
Serial.print ("G");
}
sicer če (noteLocation == 8)
{
Serial.print ("G#");
}
sicer če (noteLocation == 9)
{
Serial.print ("A");
}
sicer če (noteLocation == 10)
{
Serial.print ("A#");
}
sicer če (noteLocation == 11)
{
Serial.print ("B");
}
Serial.println (octaveRange);
}
//*****************************************************************
//Ustavi se tukaj. Za ponovni zagon pritisnite gumb za ponastavitev na Arduinu
//*****************************************************************
medtem ko (1);
}

oglejte si rawgistfile1.txt, ki ga gosti ❤ GitHub

3. korak: Namestite detektor glasbenih not

Arduino Uno povežite z računalnikom s kodo, zapisano ali naloženo v Arduino IDE. Sestavite in naložite kodo v Arduino. Vezje postavite blizu glasbenega vira. Opomba: V uvodnem videu kot vir glasbe uporabljam aplikacijo, nameščeno na tabličnem računalniku skupaj z zvočniki računalnika. Pritisnite gumb za ponastavitev na plošči Arduino in nato predvajajte noto na glasbenem viru. Po nekaj sekundah bo detektor glasbene note prikazal predvajano noto in njeno frekvenco.

Priporočena: