Sisukord:
2025 Autor: John Day | [email protected]. Viimati modifitseeritud: 2025-01-13 06:57
Üllatage oma sõpru ja perekonda selle projektiga, mis tuvastab instrumendi mängitava noodi. Selles projektis kuvatakse ligikaudne sagedus ja noodid, mida mängitakse elektroonilisel klaviatuuril, klaverirakendusel või mõnel muul instrumendil.
Üksikasjad
Selle projekti jaoks saadetakse helimooduli detektori analoogväljund Arduino Uno A0 analoogsisendisse. Analoogsignaalist võetakse proov ja see kvantiseeritakse (digiteeritakse). Autokorrelatsiooni, kaalumist ja häälestuskoodi kasutatakse põhisageduse leidmiseks kolme esimese perioodi jooksul. Seejärel võrreldakse ligikaudset põhisagedust oktavide 3, 4 ja 5 sagedustega, et määrata lähim noodisagedus. Lõpuks trükitakse ekraanile lähima sageduse arvatav märkus.
Märkus. See juhend juhendab ainult seda, kuidas projekti üles ehitada. Üksikasjade ja disaini põhjenduste kohta lisateabe saamiseks külastage seda linki: Lisateave
Tarvikud
- (1) Arduino Uno (või Genuino Uno)
- (1) Ühildub DEVMO mikrofonianduri ülitundliku heli tuvastamise mooduliga
- (1) Jooteta leivaplaat
- (1) USB-A kuni B kaabel
- Jumper juhtmed
- Muusikaline allikas (klaver, klaviatuur või kõlarirakendus kaal)
- (1) Arvuti või sülearvuti
Samm: konstrueerige noodidetektori riistvara
Arduino Uno abil konstrueerivad sellel pildil näidatud vooluahela ühendusjuhtmed, jooteta leivaplaat ja DEVMO mikrofoni anduri kõrge tundlikkusega helituvastusmoodul (või sarnane)
2. samm: programmeerige noodidetektor
Lisage Arduino IDE -s järgmine kood.
gistfile1.txt
/* |
Faili/visandi nimi: MusicalNoteDetector |
Versiooni nr: v1.0 Loodud 7. juunil 2020 |
Algne autor: Clyde A. Lettsome, PhD, PE, MEM |
Kirjeldus: see kood/visand kuvab ligikaudse sageduse ja elektroonilisel klaviatuuril või klaverirakenduses mängitava noodi. Selle projekti jaoks analoogväljund |
helimooduli detektor saadetakse Arduino Uno A0 analoogsisendisse. Analoogsignaalist võetakse proov ja see kvantiseeritakse (digiteeritakse). Autokorrelatsiooni, kaalumist ja häälestamise koodi kasutatakse |
leidke põhisagedus esimese kolme perioodi abil. Seejärel võrreldakse ligikaudset põhisagedust lähima muusikali määramiseks oktavide 3, 4 ja 5 sagedustega |
märkmete sagedus. Lõpuks trükitakse ekraanile lähima sageduse arvatav märkus. |
Litsents: see programm on tasuta tarkvara; saate seda edasi levitada ja/või muuta vastavalt GNU üldise avaliku litsentsi (GPL) versiooni 3 tingimustele või hiljem |
vaba tarkvara sihtasutuse avaldatud versioon. |
Märkused: Autoriõigus (c) 2020, autor C. A. Lettsome Services, LLC |
Lisateabe saamiseks külastage |
*/ |
#define SAMPLES 128 // Maksimaalselt 128 Arduino Uno jaoks. |
#define SAMPLING_FREQUENCY 2048 // Fs = Nyquisti põhjal peab see olema 2 korda kõrgem eeldatav sagedus. |
#define OFFSETSAMPLES 40 // kasutatakse kaabeldamiseks |
#define TUNER -3 // Reguleerige, kuni C3 on 130,50 |
ujukproovide võtmise periood; |
allkirjastamata pikad mikrosekundid; |
int X [PROOVID]; // luua reaalsete väärtuste hoidmiseks suurusega vektor VÄLJAD |
float autoCorr [PROOVID]; // looge kujutiste väärtuste hoidmiseks suurusega vektor VÄLJAD |
ujuk salvestatudNoteFreq [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]; // nihkevektori loomine |
int avgOffSet; // nihkevektori loomine |
int i, k, periodEnd, periodBegin, period, reguleerija, noteLocation, oktaavRange; |
ujuk maxValue, minValue; |
pikk summa; |
int thresh = 0; |
int numOfCycles = 0; |
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, kokku; |
bait oleku_masin = 0; |
int samplePerPeriod = 0; |
tühine seadistus () |
{ |
Seriaalne algus (115200); // 115200 seeriamonitori baudikiirus |
} |
tühine tsükkel () |
{ |
//***************************************************************** |
// Calabration Section |
//***************************************************************** |
Serial.println ("Calabrating. Palun ärge mängige noolamise ajal noote."); |
jaoks (i = 0; i <OFFSETSAMPLES; i ++) |
{ |
offSet = analogRead (0); // Loeb väärtuse analoogpingest 0 (A0), kvantiseerib selle ja salvestab selle reaalse terminina. |
//Serial.println(offSet); // kasutage seda heli tuvastamise mooduli reguleerimiseks umbes poolele või 512 -le, kui heli ei esitata. |
sumOffSet = sumOffSet + offSet ; |
} |
samplePerPeriod = 0; |
maxValue = 0; |
//***************************************************************** |
// Valmistuge A0 sisendi vastuvõtmiseks |
//***************************************************************** |
avgOffSet = ümmargune (sumOffSet / OFFSETSAMPLES); |
Serial.println ("Loendamine tagasi."); |
viivitus (1000); // paus 1 sekund |
Serial.println ("3"); |
viivitus (1000); // paus 1 sekund |
Serial.println ("2"); |
viivitus (1000); // paus 1 |
Serial.println ("1"); |
viivitus (1000); // paus 1 sekund |
Serial.println ("Esita oma noot!"); |
viivitus (250); // paus 1/4 sekundiks reaktsiooniajaks |
//***************************************************************** |
// Proovide proovide kogumine proovist A0 proovivõtuperioodiga |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Periood mikrosekundites |
jaoks (i = 0; i <PROOVID; i ++) |
{ |
mikrosekundid = mikros (); // Tagastab mikrosekundite arvu pärast seda, kui Arduino plaat hakkas praegust skripti käitama. |
X = analoogLoe (0); // Loeb väärtuse analoogpingest 0 (A0), kvantiseerib selle ja salvestab selle reaalse terminina. |
/ *järelejäänud ooteaeg proovide vahel, vajadusel sekundites */ |
samas (mikros () <(mikrosekundid + (proovivõtuperiood * 1000000))) |
{ |
// ära tee midagi, oota |
} |
} |
//***************************************************************** |
// Autokorrelatsiooni funktsioon |
//***************************************************************** |
jaoks (i = 0; i <PROOVID; i ++) // i = viivitus |
{ |
summa = 0; |
for (k = 0; k <SAMPLES - i; k ++) // Sobita signaal viivitatud signaaliga |
{ |
summa = summa + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] on signaal ja X [k+i] on viivitatud versioon |
} |
autoCorr = summa / NÄIDISED; |
// First Peak Detect State Machine |
kui (olekumasin == 0 && i == 0) |
{ |
künnis = autoCorr * 0,5; |
olekumasin = 1; |
} |
muidu, kui (oleku_masin == 1 && i> 0 && thresh 0) // oleku_masin = 1, leidke 1 periood esimese tsükli kasutamiseks |
{ |
maxValue = autoCorr ; |
} |
muidu kui (olekumasin == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodBegin = i-1; |
olekumasin = 2; |
numOfCycles = 1; |
samplePerPeriod = (perioodBegin - 0); |
periood = proovidPerPeriod; |
reguleerija = TUNER+(50,04 * exp (-0,102 * prooviPeriood)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-reguleerija; // f = fs/N |
} |
muidu, kui (olekumasin == 2 && i> 0 && thresh 0) // olekumasin = 2, leidke esimeseks ja teiseks tsükliks kaks perioodi |
{ |
maxValue = autoCorr ; |
} |
muidu kui (olekumasin == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
perioodEnd = i-1; |
olekumasin = 3; |
numOfCycles = 2; |
samplePerPeriod = (perioodEnd - 0); |
signalFrequency2 = (((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-reguleerija; // f = (2*fs)/(2*N) |
maxValue = 0; |
} |
muidu kui (olekumasin == 3 && i> 0 && thresh 0) // olekumasin = 3, leidke 1., 2. ja 3. tsükli jaoks kolm perioodi |
{ |
maxValue = autoCorr ; |
} |
muidu kui (oleku_masin == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
perioodEnd = i-1; |
olekumasin = 4; |
numOfCycles = 3; |
samplePerPeriod = (perioodEnd - 0); |
signalFrequency3 = (((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-reguleerija; // f = (3*fs)/(3*N) |
} |
} |
//***************************************************************** |
// Tulemuste analüüs |
//***************************************************************** |
kui (samplePerPeriod == 0) |
{ |
Serial.println ("Hmm ….. ma pole kindel. Kas sa üritad mind petta?"); |
} |
muidu |
{ |
// kaalumisfunktsiooni ettevalmistamine |
kokku = 0; |
kui (signalFrequency! = 0) |
{ |
kokku = 1; |
} |
kui (signalFrequency2! = 0) |
{ |
kokku = kokku + 2; |
} |
kui (signalFrequency3! = 0) |
{ |
kokku = kokku + 3; |
} |
// arvutage sagedus kaalumisfunktsiooni abil |
signalFrequencyGuess = (((1/kokku) * signalFrequency) + ((2/kokku) * signalFrequency2) + ((3/kokku) * signalFrequency3); // kaalutud sageduse leidmine |
Serial.print ("Mängitud noot on ligikaudne"); |
Serial.print (signalFrequencyGuess); // Printige sageduse oletus. |
Serial.println ("Hz"); |
// leidke oletuse põhjal oktaavivahemik |
oktaavRange = 3; |
samas (! (signalFrequencyGuess> = salvestatudNoteFreq [0] -7 && signalFrequencyGuess <= salvestatudNoteFreq [11] +7)) |
{ |
jaoks (i = 0; i <12; i ++) |
{ |
storageNoteFreq = 2 * salvestatudNoteFreq ; |
} |
octaveRange ++; |
} |
// Leia lähim noot |
minVäärtus = 10000000; |
noteLocation = 0; |
jaoks (i = 0; i <12; i ++) |
{ |
if (minValue> abs (signalFrequencyGuess-storageNoteFreq )) |
{ |
minValue = abs (signalFrequencyGuess-storageNoteFreq ); |
noteLocation = i; |
} |
} |
// Märkme printimine |
Serial.print ("Ma arvan, et sa mängisid"); |
if (noteLocation == 0) |
{ |
Serial.print ("C"); |
} |
muidu kui (noteLocation == 1) |
{ |
Serial.print ("C#"); |
} |
muidu kui (noteLocation == 2) |
{ |
Serial.print ("D"); |
} |
muidu kui (noteLocation == 3) |
{ |
Serial.print ("D#"); |
} |
muidu kui (noteLocation == 4) |
{ |
Serial.print ("E"); |
} |
muidu kui (noteLocation == 5) |
{ |
Serial.print ("F"); |
} |
muidu kui (noteLocation == 6) |
{ |
Serial.print ("F#"); |
} |
muidu kui (noteLocation == 7) |
{ |
Serial.print ("G"); |
} |
muidu kui (noteLocation == 8) |
{ |
Serial.print ("G#"); |
} |
muidu kui (noteLocation == 9) |
{ |
Serial.print ("A"); |
} |
muidu kui (noteLocation == 10) |
{ |
Serial.print ("A#"); |
} |
muidu kui (noteLocation == 11) |
{ |
Serial.print ("B"); |
} |
Serial.println (octaveRange); |
} |
//***************************************************************** |
//Peatu siin. Taaskäivitamiseks vajutage Arduino lähtestamisnuppu |
//***************************************************************** |
samas (1); |
} |
vaadake rawgistfile1.txt, mille hostiks on GitHub ❤
3. samm: seadistage noodidetektor
Ühendage Arduino Uno arvutiga, kirjutades või laadides Arduino IDE -sse koodi. Koostage ja laadige kood üles Arduino. Asetage vooluring muusikaallika lähedale. Märkus. Sissejuhatavas videos kasutan muusikaallikana tahvelarvutisse installitud rakendust koos arvuti kõlaritega. Vajutage Arduino Boardi lähtestamisnuppu ja esitage muusikaallikas noot. Mõne sekundi pärast kuvab noodidetektor mängitud noodi ja selle sageduse.