Noodidetektor: 3 sammu
Noodidetektor: 3 sammu
Anonim
Image
Image

Ü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

Seadistage noodidetektor
Seadistage noodidetektor

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.