Sadržaj:

Detektor muzičkih nota: 3 koraka
Detektor muzičkih nota: 3 koraka

Video: Detektor muzičkih nota: 3 koraka

Video: Detektor muzičkih nota: 3 koraka
Video: ЗАПРЕЩЁННЫЕ ТОВАРЫ с ALIEXPRESS 2023 ШТРАФ и ТЮРЬМА ЛЕГКО! 2024, Novembar
Anonim
Image
Image

Zadivite svoje prijatelje i porodicu ovim projektom koji otkriva notu koju svira neki instrument. Ovaj će projekt prikazati približnu frekvenciju, kao i muzičku notu koja se svira na elektronskoj klavijaturi, aplikaciji za klavir ili bilo kojem drugom instrumentu.

Detalji

Za ovaj projekt, analogni izlaz sa detektora zvučnog modula šalje se na A0 analogni ulaz Arduino Uno. Analogni signal se uzorkuje i kvantizuje (digitalizuje). Kod za automatsku korelaciju, ponderiranje i ugađanje koristi se za pronalaženje osnovne frekvencije pomoću prva 3 perioda. Približna osnovna frekvencija zatim se uspoređuje s frekvencijama u rasponu oktava 3, 4 i 5 kako bi se odredila najbliža frekvencija glazbenih nota. Konačno, pogodna bilješka za najbližu frekvenciju se ispisuje na ekranu.

Napomena: Ova instrukcija se fokusira samo na način izgradnje projekta. Za više informacija o detaljima i opravdanjima dizajna posjetite ovu vezu: Više informacija

Supplies

  • (1) Arduino Uno (ili Genuino Uno)
  • (1) Kompatibilan sa DEVMO senzorom mikrofona senzora visoke osjetljivosti za otkrivanje zvuka
  • (1) Oplata za lemljenje
  • (1) Kabel USB-A do B
  • Žice za kratkospojnike
  • Izvor muzike (klavir, klavijatura ili paino aplikacija sa zvučnicima)
  • (1) Računar ili laptop

Korak 1: Konstruirajte hardver za detektor muzičkih nota

Postavite detektor muzičkih nota
Postavite detektor muzičkih nota

Koristeći Arduino Uno, spojne žice, ploča za lemljenje i DEVMO senzorski mikrofonski senzor visoke osjetljivosti modula za otkrivanje zvuka (ili slično) konstruiraju krug prikazan na ovoj slici

Korak 2: Programirajte detektor muzičkih nota

U Arduino IDE dodajte sljedeći kôd.

gistfile1.txt

/*
Naziv datoteke/skice: MusicalNoteDetector
Verzija br.: v1.0 Kreirano 7. lipnja 2020
Originalni autor: Clyde A. Lettsome, PhD, PE, MEM
Opis: Ovaj kod/skica prikazuje približnu frekvenciju, kao i muzičku notu koja se svira na aplikaciji za elektronsku klavijaturu ili klavir. Za ovaj projekt, analogni izlaz iz
Detektor zvučnog modula šalje se na analogni ulaz A0 Arduino Uno. Analogni signal se uzorkuje i kvantizuje (digitalizuje). Kod autokorelacije, ponderiranja i ugađanja je navikao
pronaći osnovnu frekvenciju koristeći prva 3 perioda. Približna osnovna frekvencija se zatim uspoređuje s frekvencijama u oktavama 3, 4 i 5 kako bi se odredio najbliži mjuzikl
notna frekvencija. Konačno, pogodna bilješka za najbližu frekvenciju se ispisuje na ekranu.
Licenca: Ovaj program je besplatan softver; možete ga dalje distribuirati i/ili mijenjati pod uslovima GNU Opće javne licence (GPL) verzije 3, ili bilo koje kasnije
verziju po vašem izboru, koju je objavila Fondacija za slobodni softver.
Napomene: Autorska prava (c) 2020. C. A. Lettsome Services, LLC
Za više informacija posjetite
*/
#define SAMPLES 128 // Max 128 za Arduino Uno.
#define SAMPLING_FREQUENCY 2048 // Fs = Na osnovu Nyquista, mora biti 2 puta najveća očekivana frekvencija.
#define OFFSETSAMPLES 40 // koristi se za kalabriranje
#define TUNER -3 // Podešavajte dok C3 ne bude 130,50
float samplingPeriod;
nepotpisane duge mikrosekunde;
int X [UZORCI]; // kreiramo vektor veličine SAMPLES za držanje stvarnih vrijednosti
float autoCorr [UZORCI]; // kreiramo vektor SAMPLES veličine za držanje imaginarnih vrijednosti
float storedNoteFreq [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]; // kreiranje ofsetnog vektora
int avgOffSet; // kreiranje ofsetnog vektora
int i, k, periodEnd, periodBegin, period, podešivač, noteLocation, oktavaRange;
float maxValue, minValue;
duga suma;
int thresh = 0;
int numOfCycles = 0;
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, ukupno;
bajt state_machine = 0;
int uzorciPerPeriod = 0;
void setup ()
{
Serial.begin (115200); // 115200 Brzina prijenosa za serijski monitor
}
void loop ()
{
//*****************************************************************
// Odjeljak kalibracije
//*****************************************************************
Serial.println ("Kalabriranje. Molimo vas da ne svirate nikakve note tokom kalibracije.");
za (i = 0; i <OFFSETSAMPLES; i ++)
{
offSet = analogRead (0); // Čita vrijednost s analognog pina 0 (A0), kvantizira je i sprema kao pravi pojam.
//Serial.println(offSet); // koristite ovo za podešavanje modula za otkrivanje zvuka na približno pola ili 512 kada se ne reproducira zvuk.
sumOffSet = sumOffSet + offSet ;
}
uzorciPerPeriod = 0;
maxValue = 0;
//*****************************************************************
// Pripremite se za prihvaćanje unosa iz A0
//*****************************************************************
avgOffSet = okruglo (sumOffSet / OFFSETSAMPLES);
Serial.println ("Odbrojavanje".);
kašnjenje (1000); // pauzirajte 1 sekundu
Serial.println ("3");
kašnjenje (1000); // pauzirajte 1 sekundu
Serial.println ("2");
kašnjenje (1000); // pauzira za 1
Serial.println ("1");
kašnjenje (1000); // pauzirajte 1 sekundu
Serial.println ("Sviraj svoju notu!");
kašnjenje (250); // pauzirajte 1/4 sekunde za vrijeme reakcije
//*****************************************************************
// Prikupite uzorke uzoraka iz A0 sa periodom uzorkovanja Period uzorkovanja
//*****************************************************************
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Period u mikrosekundama
za (i = 0; i <UZORCI; i ++)
{
microSeconds = micros (); // Vraća broj mikrosekundi otkako je Arduino ploča počela izvoditi trenutnu skriptu.
X = analogRead (0); // Čita vrijednost s analognog pina 0 (A0), kvantizira je i sprema kao pravi pojam.
/ *preostalo vrijeme čekanja između uzoraka ako je potrebno u sekundama */
while (micros () <(microSeconds + (samplingPeriod * 1000000)))
{
// ne radite ništa samo čekajte
}
}
//*****************************************************************
// Funkcija autokorelacije
//*****************************************************************
for (i = 0; i <SAMPLES; i ++) // i = kašnjenje
{
zbir = 0;
for (k = 0; k <SAMPLES - i; k ++) // Uskladite signal sa odgođenim signalom
{
zbir = zbir + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] je signal, a X [k+i] odgođena verzija
}
autoCorr = zbir / UZORCI;
// First Machine Detect State Machine
if (state_machine == 0 && i == 0)
{
thresh = autoCorr * 0,5;
stanje_mašina = 1;
}
inače if (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, pronađite 1 period za korištenje prvog ciklusa
{
maxValue = autoCorr ;
}
inace if (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodBegin = i-1;
stanje_mašina = 2;
numOfCycles = 1;
uzorciPerPeriod = (periodBegin - 0);
period = samplesPerPeriod;
podešivač = TUNER+(50.04 * exp (-0.102 * samplePerPeriod));
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-podešivač; // f = fs/N
}
inace if (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, naci 2 perioda za prvi i drugi ciklus
{
maxValue = autoCorr ;
}
inace if (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
stanje_mašina = 3;
numOfCycles = 2;
uzorciPerPeriod = (periodEnd - 0);
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-podešivač; // f = (2*fs)/(2*N)
maxValue = 0;
}
inace if (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, naci 3 perioda za 1., 2. i 3. ciklus
{
maxValue = autoCorr ;
}
inace if (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
state_machine = 4;
numOfCycles = 3;
uzorciPerPeriod = (periodEnd - 0);
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-podešivač; // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// Analiza rezultata
//*****************************************************************
if (uzorciperioda == 0)
{
Serial.println ("Hmm ….. nisam siguran. Pokušavate li me prevariti?");
}
else
{
// priprema funkcija ponderiranja
ukupno = 0;
if (signalFrequency! = 0)
{
ukupno = 1;
}
if (signalFrequency2! = 0)
{
ukupno = ukupno + 2;
}
if (signalFrequency3! = 0)
{
ukupno = ukupno + 3;
}
// izračunajte frekvenciju pomoću funkcije ponderiranja
signalFrequencyGuess = ((1/ukupno) * signalFrequency) + ((2/ukupno) * signalFrequency2) + ((3/ukupno) * signalFrequency3); // pronaći ponderiranu frekvenciju
Serial.print ("Nota koju ste odsvirali je otprilike");
Serial.print (signalFrequencyGuess); // Odštampajte frekvenciju.
Serial.println ("Hz.");
// pronađite oktavni raspon na osnovu pretpostavke
octaveRange = 3;
while (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7))
{
za (i = 0; i <12; i ++)
{
storedNoteFreq = 2 * storedNoteFreq ;
}
octaveRange ++;
}
// Pronađite najbližu bilješku
minValue = 10000000;
noteLocation = 0;
za (i = 0; i <12; i ++)
{
if (minValue> abs (signalFrequencyGuess-storedNoteFreq ))
{
minValue = abs (signalFrequencyGuess-storedNoteFreq );
noteLocation = i;
}
}
// Odštampajte belešku
Serial.print ("Mislim da ste svirali");
if (noteLocation == 0)
{
Serial.print ("C");
}
inače if (noteLocation == 1)
{
Serial.print ("C#");
}
inače ako (noteLocation == 2)
{
Serial.print ("D");
}
inače if (noteLocation == 3)
{
Serial.print ("D#");
}
inace if (noteLocation == 4)
{
Serial.print ("E");
}
inače if (noteLocation == 5)
{
Serial.print ("F");
}
inace if (noteLocation == 6)
{
Serial.print ("F#");
}
inače ako (noteLocation == 7)
{
Serial.print ("G");
}
inace if (noteLocation == 8)
{
Serial.print ("G#");
}
inače if (noteLocation == 9)
{
Serial.print ("A");
}
inače if (noteLocation == 10)
{
Serial.print ("A#");
}
inače if (noteLocation == 11)
{
Serial.print ("B");
}
Serial.println (octaveRange);
}
//*****************************************************************
//Zaustavi ovdje. Pritisnite dugme za resetiranje na Arduinu za ponovno pokretanje
//*****************************************************************
while (1);
}

pogledajte rawgistfile1.txt hostirano sa ❤ na GitHub -u

Korak 3: Postavite detektor muzičkih nota

Povežite Arduino Uno sa računarom pomoću koda napisanog ili učitanog u Arduino IDE. Sastavite i prenesite kôd na Arduino. Postavite strujno kolo blizu izvora muzike. Napomena: U uvodnom videu kao izvor muzike koristim aplikaciju instaliranu na tabletu zajedno sa zvučnicima na računaru. Pritisnite dugme za resetiranje na Arduino ploči, a zatim pustite notu na izvoru muzike. Nakon nekoliko sekundi, detektor muzičkih nota će prikazati odsviranu notu i njenu frekvenciju.

Preporučuje se: