Orodha ya maudhui:

Kigunduzi cha Muziki: Hatua 3
Kigunduzi cha Muziki: Hatua 3

Video: Kigunduzi cha Muziki: Hatua 3

Video: Kigunduzi cha Muziki: Hatua 3
Video: АРАМ ЗАМ ЗАМ - Песни Для Детей - Развивающие Мультики 2024, Novemba
Anonim
Image
Image

Shangaza marafiki wako na familia na mradi huu ambao hugundua maandishi yaliyochezwa na ala. Mradi huu utaonyesha masafa ya takriban na noti ya muziki iliyochezwa kwenye kibodi ya elektroniki, programu ya piano au chombo chochote kingine.

Maelezo

Kwa mradi huu, pato la analog kutoka kwa kigunduzi cha moduli ya sauti hutumwa kwa pembejeo ya Analog ya A0 ya Arduino Uno. Ishara ya Analog ni sampuli na hesabu (iliyokadiriwa). Msimbo wa kiotomatiki, uzani na urekebishaji hutumiwa kupata masafa ya kimsingi ukitumia vipindi 3 vya kwanza. Mzunguko wa kimsingi wa karibu unalinganishwa na masafa katika octave 3, 4, na 5 anuwai ili kujua masafa ya karibu zaidi ya maandishi ya muziki. Mwishowe noti iliyodhaniwa ya masafa ya karibu zaidi imechapishwa kwenye skrini.

Kumbuka: Hii inaelekezwa tu juu ya jinsi ya kujenga mradi. Kwa habari zaidi juu ya maelezo na uhalali wa muundo, tafadhali tembelea kiunga hiki: Habari zaidi

Vifaa

  • (1) Arduino Uno (au Genuino Uno)
  • (1) Moduli ya maikrofoni ya DEVMO Sura ya Juu ya Utambuzi wa Sauti Inaambatana
  • (1) Bodi ya mkate isiyo na Solder
  • (1) USB-A hadi C Cable
  • Waya za jumper
  • Chanzo cha muziki (piano, kibodi au programu ya paino na spika)
  • (1) Kompyuta au kompyuta ndogo

Hatua ya 1: Jenga vifaa kwa Kigunduzi cha Kumbuka Muziki

Sanidi Kigunduzi cha Kumbuka Muziki
Sanidi Kigunduzi cha Kumbuka Muziki

Kutumia Arduino Uno, nyaya za unganisho, ubao wa mkate usio na waya na Moduli ya Kugundua Sauti ya Upataji Sauti ya DEVMO (au sawa) jenga mzunguko ulioonyeshwa kwenye picha hii

Hatua ya 2: Panga Kigunduzi cha Kumbuka Muziki

Katika IDE ya Arduino, ongeza nambari ifuatayo.

faili1.txt

/*
Faili / Jina la Mchoro: MusicalNoteDetector
Toleo Na.: V1.0 Iliundwa 7 Juni, 2020
Mwandishi Asili: Clyde A. Lettsome, PhD, PE, MEM
Maelezo: Msimbo / mchoro huu unaonyesha masafa ya takriban na noti ya muziki iliyochezwa kwenye kibodi ya elektroniki au programu ya piano. Kwa mradi huu, pato la analog kutoka
detector ya moduli ya sauti inatumwa kwa pembejeo ya Analog ya A0 ya Arduino Uno. Ishara ya Analog ni sampuli na hesabu (iliyokadiriwa). Msimbo wa kiotomatiki, uzani na urekebishaji hutumiwa
pata mzunguko wa kimsingi ukitumia vipindi 3 vya kwanza. Mzunguko wa kimsingi wa karibu unalinganishwa na masafa katika octave 3, 4, na 5 anuwai kuamua muziki wa karibu zaidi
mzunguko wa kumbuka. Mwishowe noti iliyodhaniwa ya masafa ya karibu zaidi imechapishwa kwenye skrini.
Leseni: Programu hii ni programu ya bure; unaweza kuisambaza tena na / au kuibadilisha chini ya masharti ya GNU General Public License (GPL) toleo la 3, au baadaye
toleo la chaguo lako, kama lilivyochapishwa na Free Software Foundation.
Vidokezo: Hakimiliki (c) 2020 na C. A. Lettsome Services, LLC
Kwa habari zaidi tembelea
*/
#fafanua SAMPILI 128 // Max 128 ya Arduino Uno.
#fafanua SAMPLING_FREQUENCY 2048 // Fs = Kulingana na Nyquist, lazima iwe mara 2 ya kiwango cha juu kinachotarajiwa.
#fafanua MFUMO WA SAMPILE 40 // kutumika kwa madhumuni ya kutuliza
#fafanua KITENGO -3 // Kurekebisha mpaka C3 ni 130.50
sampuli ya kuelea Kipindi;
microSeconds ndefu ambazo hazijasainiwa;
int X [SAMPILI]; // tengeneza vector ya ukubwa SAMPLES kushikilia maadili halisi
kuelea autoCorr [SAMPILI]; // tengeneza vector ya ukubwa SAMPILI kushikilia maadili ya kufikiria
kuelea kuhifadhiwaNoteFreq [12] = {130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185, 196, 207.65, 220, 233.08, 246.94};
jumla sumOffSet = 0;
int offSet [OFFSETSAMPLES]; // tengeneza vector ya kukabiliana
int avgOffSet; // tengeneza vector ya kukabiliana
int i, k, kipindiEnd, kipindi Anzisha, kipindi, kiboreshaji, dokezoLocation, octaveRange;
kuelea maxValue, minValue;
jumla ndefu;
upuraji = 0;
int numOfCycles = 0;
ishara ya kuelea Frequency, isharaFrequency2, isharaFrequency3, isharaFrequencyGuess, jumla;
state_machine byte = 0;
sampuli za Kipindi = 0;
kuanzisha batili ()
{
Serial. Kuanza (115200); // Kiwango cha Baud cha 115200 cha Monitor Serial
}
kitanzi batili ()
{
//*****************************************************************
// Sehemu ya Uhalalishaji
//*****************************************************************
Serial.
kwa (i = 0; i <OFFSETSAMPLES; i ++)
{
offSet = AnalogSoma (0); // Inasoma thamani kutoka kwa pini ya analog 0 (A0), hesabu na uihifadhi kama neno halisi.
//Serial.println (offSet); // tumia hii kurekebisha moduli ya kugundua sauti iwe karibu nusu au 512 wakati hakuna sauti inayochezwa.
sumOffSet = sumOffSet + offSet ;
}
sampuli Kipindi = 0;
Thamani ya max = 0;
//*****************************************************************
// Jitayarishe kukubali maoni kutoka kwa A0
//*****************************************************************
avgOffSet = pande zote (sumOffSet / OFFSETSAMPLES);
Serial.println ("Kuhesabu chini.");
kuchelewesha (1000); // pumzika kwa sekunde 1
Serial.println ("3");
kuchelewesha (1000); // pumzika kwa sekunde 1
Serial.println ("2");
kuchelewesha (1000); // pumzika kwa 1
Serial.println ("1");
kuchelewesha (1000); // pumzika kwa sekunde 1
Serial.println ("Cheza dokezo lako!");
kuchelewesha (250); // pumzika kwa sekunde 1/4 kwa wakati wa majibu
//*****************************************************************
// Kusanya sampuli za SAMPILI kutoka A0 na kipindi cha sampuli ya Kipindi cha sampuli
//*****************************************************************
sampuliPeriod = 1.0 / SAMPLING_FREQUENCY; // Kipindi katika microseconds
kwa (i = 0; i <SAMPLES; i ++)
{
MicroSeconds = micros (); // Hurejesha idadi ya mikrofoni tangu bodi ya Arduino ilipoanza kutumia hati ya sasa.
X = AnalogSoma (0); // Inasoma thamani kutoka kwa pini ya analog 0 (A0), hesabu na uihifadhi kama neno halisi.
/ * iliyobaki wakati wa kusubiri kati ya sampuli ikiwa ni lazima kwa sekunde * /
wakati (micros () <(microSeconds + (sampuli Kipindi * 1000000)))
{
// usifanye chochote subiri tu
}
}
//*****************************************************************
// Kazi ya Autocorrelation
//*****************************************************************
kwa (i = 0; i <SAMPLES; i ++) // i = kuchelewesha
{
jumla = 0;
kwa (k = 0; k <SAMPILI - i; k ++) // Ishara ya mechi na ishara iliyocheleweshwa
{
jumla = jumla + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] ni ishara na X [k + i] ni toleo lililocheleweshwa
}
autoCorr = jumla / SAMPILI;
// Kilele cha kwanza Gundua Mashine ya Serikali
ikiwa (state_machine == 0 && i == 0)
{
pura = autoCorr * 0.5;
mashine_mashine = 1;
}
vinginevyo ikiwa (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, pata kipindi 1 cha kutumia mzunguko wa kwanza
{
maxValue = autoCorr ;
}
vinginevyo ikiwa (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
kipindiAnza = i-1;
mashine_mashine = 2;
Nambari za Mzunguko = 1;
sampuliPerPeriod = (kipindi cha Kuanza - 0);
kipindi = sampuliPerPeriod;
kiboreshaji = TUNER + (50.04 * exp (-0.102 * sampuliPerPeriod));
signalFrequency = (((SAMPLING_FREQUENCY) / (samplesPerPeriod)) - kiboreshaji; // f = fs / N
}
vinginevyo ikiwa (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, pata vipindi 2 kwa mzunguko wa 1 na 2
{
maxValue = autoCorr ;
}
vinginevyo ikiwa (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
kipindiEnd = i-1;
mashine_ya hali = 3;
Nambari za Mzunguko = 2;
sampuliPerPeriod = (kipindiEnd - 0);
signalFrequency2 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - kiboreshaji; // f = (2 * fs) / (2 * N)
Thamani ya max = 0;
}
vinginevyo ikiwa (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, pata vipindi 3 kwa mzunguko wa 1, 2 na 3
{
maxValue = autoCorr ;
}
vinginevyo ikiwa (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
kipindiEnd = i-1;
mashine_mashine = 4;
Nambari za Mzunguko = 3;
sampuliPerPeriod = (kipindiEnd - 0);
signalFrequency3 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - kiboreshaji; // f = (3 * fs) / (3 * N)
}
}
//*****************************************************************
// Uchambuzi wa Matokeo
//*****************************************************************
ikiwa (sampuliPerPeriod == 0)
{
Serial.println ("Hmm….. sina hakika. Je! Unajaribu kunidanganya?");
}
mwingine
{
// kuandaa kazi ya uzani
jumla = 0;
ikiwa (signalFrequency! = 0)
{
jumla = 1;
}
ikiwa (signalFrequency2! = 0)
{
jumla = jumla + 2;
}
ikiwa (signalFrequency3! = 0)
{
jumla = jumla + 3;
}
// mahesabu ya masafa kwa kutumia kazi ya uzani
signalFrequencyGuess = ((1 / jumla) * signalFrequency) + ((2 / jumla) * signalFrequency2) + ((3 / jumla) * signalFrequency3); // pata masafa yenye uzito
Serial.print ("Ujumbe uliocheza ni takriban");
Serial.print (signalFrequencyGuess); // Chapisha nadhani ya masafa.
Serial.println ("Hz.");
// pata safu ya octave kulingana na nadhani
octaveRange = 3;
wakati (! (signalFrequencyGuess> = imehifadhiwaNoteFreq [0] -7 && signalFrequencyGuess <= imehifadhiwaNoteFreq [11] +7))
{
kwa (i = 0; i <12; i ++)
{
kuhifadhiNoteFreq = 2 * kuhifadhiNoteFreq ;
}
octaveRange ++;
}
// Pata barua ya karibu zaidi
Thamani ya min = 10000000;
noteLocation = 0;
kwa (i = 0; i <12; i ++)
{
ikiwa (minValue> abs (signalFrequencyGuess-kuhifadhiwaNoteFreq ))
{
minValue = abs (signalFrequencyGuess-iliyohifadhiwaNoteFreq );
noteLocation = i;
}
}
// Chapisha maandishi
Serial.print ("Nadhani umecheza");
ikiwa (kumbukaLocation == 0)
{
Serial.print ("C");
}
vinginevyo ikiwa (kumbukaLocation == 1)
{
Serial.print ("C #");
}
vinginevyo ikiwa (kumbukaLocation == 2)
{
Serial.print ("D");
}
vinginevyo ikiwa (kumbukaLocation == 3)
{
Serial.print ("D #");
}
vinginevyo ikiwa (kumbukaLocation == 4)
{
Serial.print ("E");
}
vinginevyo ikiwa (kumbukaLocation == 5)
{
Serial.print ("F");
}
vinginevyo ikiwa (kumbukaLocation == 6)
{
Serial.print ("F #");
}
vinginevyo ikiwa (kumbukaLocation == 7)
{
Serial.print ("G");
}
vinginevyo ikiwa (kumbukaLocation == 8)
{
Serial.print ("G #");
}
vinginevyo ikiwa (kumbukaLocation == 9)
{
Serial.print ("A");
}
vinginevyo ikiwa (kumbukaLocation == 10)
{
Serial.print ("A #");
}
vinginevyo ikiwa (kumbukaLocation == 11)
{
Serial.print ("B");
}
Serial.println (octaveRange);
}
//*****************************************************************
// Acha hapa. Piga kitufe cha kuweka upya kwenye Arduino ili uanze tena
//*****************************************************************
wakati (1);
}

angalia rawgistfile1.txt iliyoangaziwa na ❤ na GitHub

Hatua ya 3: Sanidi Kigunduzi cha Kumbuka Muziki

Unganisha Arduino Uno na PC na nambari iliyoandikwa au kupakiwa kwenye Arduino IDE. Kusanya na kupakia nambari hiyo kwa Arduino. Weka mzunguko karibu na chanzo cha muziki. Kumbuka: Katika video ya utangulizi, ninatumia programu iliyosanikishwa kwenye kompyuta kibao kwa kushirikiana na spika za PC kama chanzo cha muziki. Piga kitufe cha kuweka upya kwenye Bodi ya Arduino kisha ucheze dokezo kwenye chanzo cha muziki. Baada ya sekunde chache, Kigunduzi cha Muziki cha Kumbuka kitaonyesha noti iliyochezwa na masafa yake.

Ilipendekeza: