Kazalo:
- Zaloge
- 1. korak: Zgradite strojno opremo za detektor glasbenih not
- 2. korak: Programirajte detektor glasbenih not
- 3. korak: Namestite detektor glasbenih not
Video: Detektor glasbenih not: 3 koraki
2024 Avtor: John Day | [email protected]. Nazadnje spremenjeno: 2024-01-30 12:02
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
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:
Detektor glasbenih zapiskov Arduino: 3 koraki
Detektor glasbenih zapisov Arduino: Odkrivanje glasbenih zapisov iz zvočnega signala je težko, zlasti na Arduinu zaradi omejenega pomnilnika in procesorske moči. Na splošno opomba ni čisti sinusni val, ki otežuje odkrivanje. Če vzamemo frekvenčno transformacijo va
Stroj za kolo glasbenih vtisov nocojšnje oddaje: 7 korakov
Stroj za glasbene impresije Tonight Show -a: Navdih za ta stroj je iz segmenta Tonight Show -a z Jimmyjem Fallonom v klicu "Kolo glasbenih vtisov". Najprej pritisnete gumb na škatli in na plošči LCD se prikaže naključni pevec in pesem. Potem morate posnemati
IOT detektor dima: Posodobite obstoječi detektor dima z IOT: 6 korakov (s slikami)
IOT detektor dima: Posodobite obstoječi detektor dima z IOT: Seznam sodelavcev, Izumitelj: Tan Siew Chin, Tan Yit Peng, Tan Wee Heng Nadzornik: dr. Chia Kim Seng Oddelek za mehatronski in robotski inženiring, Fakulteta za elektrotehniko in elektroniko, Univerza Tun Hussein Onn Malaysia. Distributer
Not So Basic Batch Tutorial: 6 korakov
Not So Basic Batch Tutorial: V prejšnji vadnici smo se naučili osnove pisanja paketnih datotek. Če nimate pojma, kaj je paket, pa se ga želite naučiti, si oglejte "Zelo osnovni paketni vadnik". izvedeli boste naprednejše ukaze in kako
Not Hard Youtube Video Downloads: 4 Koraki
Not Hard Youtube Video Downloads: V tem navodilu vam bom pokazal, kako prenesete " Youtube " video posnetki hitro. Prosim, uživajte v mojih navodilih in komentirajte, ocenite ali celo postavite kakršna koli vprašanja. Uživajte