Mundarija:

Musiqiy notalar detektori: 3 qadam
Musiqiy notalar detektori: 3 qadam

Video: Musiqiy notalar detektori: 3 qadam

Video: Musiqiy notalar detektori: 3 qadam
Video: 3 РЕЦЕПТА из КУРИНОЙ ПЕЧЕНИ/ ПАШТЕТ!! ГОСТИ БУДУТ В ШОКЕ!! 2024, Noyabr
Anonim
Image
Image

Asbob chalayotgan notani aniqlaydigan ushbu loyiha yordamida do'stlaringiz va oilangizni hayratda qoldiring. Bu loyihada taxminiy chastota, shuningdek elektron klaviatura, pianino ilovasi yoki boshqa asbobda chalilgan musiqiy nota ko'rsatiladi.

Tafsilotlar

Ushbu loyiha uchun ovozli modul detektorining analog chiqishi Arduino Uno -ning A0 analog kirishiga yuboriladi. Analog signal namuna olinadi va kvantlanadi (raqamli). Avtokorrelyatsiya, tortish va sozlash kodi dastlabki 3 davr yordamida asosiy chastotani topish uchun ishlatiladi. Taxminan asosiy chastota 3, 4 va 5 oktavalardagi chastotalar bilan taqqoslanib, eng yaqin musiqiy nota chastotasini aniqlaydi. Nihoyat, eng yaqin chastota uchun taxmin qilingan eslatma ekranga chiqariladi.

Eslatma: Bu ko'rsatma faqat loyihani qanday qurishga qaratilgan. Tafsilotlar va dizayn asoslari haqida qo'shimcha ma'lumot olish uchun quyidagi havolaga tashrif buyuring: Qo'shimcha ma'lumot

Ta'minotlar

  • (1) Arduino Uno (yoki Genuino Uno)
  • (1) DEVMO mikrofon sensori yuqori sezuvchanlik tovushni aniqlash moduli
  • (1) lehimsiz non paneli
  • (1) USB-A-B kabeli
  • Jumper simlari
  • Musiqiy manba (pianino, klaviatura yoki karnaylar bilan og'riqli dastur)
  • (1) Kompyuter yoki noutbuk

1 -qadam: Musiqiy notalar detektori uchun uskunalar yaratish

Musiqiy notalar detektorini o'rnating
Musiqiy notalar detektorini o'rnating

Arduino Uno -dan foydalanib, ulanish simlari, lehimsiz non paneli va DEVMO mikrofon sensori yuqori sezuvchanlik tovushni aniqlash moduli (yoki shunga o'xshash) ushbu rasmda ko'rsatilgan sxemani tuzadi.

2 -qadam: Musiqiy notalar detektorini dasturlash

Arduino IDE -ga quyidagi kodni qo'shing.

gistfile1.txt

/*
Fayl/eskiz nomi: MusicalNoteDetector
Versiya raqami: v1.0 2020 yil 7 -iyunda yaratilgan
Asl muallif: Clyde A. Lettsome, PhD, PE, MEM
Tavsif: Ushbu kod/eskizda taxminiy chastota, shuningdek elektron klaviatura yoki pianino ilovasida yangragan musiqiy nota ko'rsatiladi. Ushbu loyiha uchun analog chiqish
tovush moduli detektori Arduino Uno -ning A0 analog kirishiga yuboriladi. Analog signal namuna olinadi va kvantlanadi (raqamli). Avtokorrelyatsiya, tortish va sozlash kodi ishlatiladi
dastlabki 3 davrdan foydalanib, asosiy chastotani toping. Taxminan asosiy chastota 3, 4 va 5 oktavalardagi chastotalar bilan taqqoslanib, eng yaqin musiqani aniqlaydi.
chastotaga e'tibor bering. Nihoyat, eng yaqin chastota uchun taxmin qilingan eslatma ekranga chiqariladi.
Litsenziya: Bu dastur bepul dasturiy ta'minot; siz uni GNU General Public License (GPL) 3 -versiya shartlari bo'yicha yoki undan keyinroq qayta tarqatishingiz va/yoki o'zgartirishingiz mumkin.
Siz tanlagan versiya, Free Software Foundation tomonidan e'lon qilingan.
Eslatmalar: Mualliflik huquqi (c) 2020 tomonidan C. A. Lettsome Services, MChJ
Qo'shimcha ma'lumot olish uchun tashrif buyuring
*/
#DAMPLES 128 ni aniqlang // Arduino Uno uchun maksimal 128.
#define SAMPLING_FREQUENCY 2048 // Fs = Nyquist asosida, kutilgan eng yuqori chastotadan 2 barobar ko'p bo'lishi kerak.
#define OFFSETSAMPLES 40 // kalabratsiya qilish uchun ishlatiladi
#define TUNER -3 // C3 130.50 ga qadar sozlang
float namuna olish davri;
imzosiz uzun mikrosaniyalar;
int X [MASALALAR]; // haqiqiy qiymatlarni ushlab turish uchun SAMPLES hajmli vektor yaratish
float autoCorr [SAMPLES]; // xayoliy qiymatlarni ushlab turish uchun SAMPLES hajmli vektor yaratish
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]; // ofset vektorini yaratish
int avgOffSet; // ofset vektorini yaratish
int i, k, periodEnd, periodBegin, davr, sozlagich, noteLocation, octaveRange;
suzuvchi maxValue, minValue;
uzoq summa;
int thres = 0;
int numOfCycles = 0;
float signalFrekans, signalFrequency2, signalFrequency3, signalFrequencyGuess, jami;
bayt holati_mashinasi = 0;
int samplePerPeriod = 0;
bo'sh o'rnatish ()
{
Serial.begin (115200); // Serial monitor uchun 115200 Baud tezligi
}
bo'sh halqa ()
{
//*****************************************************************
// Kalabratsiya bo'limi
//*****************************************************************
Serial.println ("Calabrating. Iltimos, kalabratsiya paytida hech qanday yozuv o'ynamang.");
uchun (i = 0; i <OFFSETSAMPLES; i ++)
{
offSet = analogRead (0); // 0 (A0) analog pinidan qiymatni o'qiydi, uning miqdorini aniqlang va haqiqiy atama sifatida saqlang.
//Serial.println(offSet ); // ovozni aniqlash modulini ovoz eshitilmaganda taxminan yarmiga yoki 512 ga sozlash uchun foydalaning.
sumOffSet = sumOffSet + offSet ;
}
samplePerPeriod = 0;
maxValue = 0;
//*****************************************************************
// A0 dan kirishni qabul qilishga tayyorlaning
//*****************************************************************
avgOffSet = dumaloq (sumOffSet / OFFSETSAMPLES);
Serial.println ("Sanash.");
kechikish (1000); // 1 soniya pauza qiling
Serial.println ("3");
kechikish (1000); // 1 soniya pauza qiling
Serial.println ("2");
kechikish (1000); // 1 pauza
Serial.println ("1");
kechikish (1000); // 1 soniya pauza qiling
Serial.println ("Eslatmani o'ynang!");
kechikish (250); // reaktsiya vaqti uchun 1/4 soniya pauza
//*****************************************************************
// A0 dan SAMPLES namunalarini yig'ish
//*****************************************************************
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Davr mikrosaniyalarda
uchun (i = 0; i <SAMPLES; i ++)
{
microSeconds = micros (); // Arduino platasi joriy skriptni ishga tushirganidan beri mikrosaniyalar sonini qaytaradi.
X = analogRead (0); // 0 (A0) analog pinidan qiymatni o'qiydi, uning miqdorini aniqlang va haqiqiy atama sifatida saqlang.
/ *namunalar orasidagi kutish vaqti, agar kerak bo'lsa, soniyalarda */
while (micros () <(microSeconds + (samplePeriod * 1000000)))
{
// hech narsa qilmang, kuting
}
}
//*****************************************************************
// Avtokorrelyatsiya funktsiyasi
//*****************************************************************
uchun (i = 0; i <SAMPLES; i ++) // i = kechikish
{
sum = 0;
for (k = 0; k <SAMPLES - i; k ++) // Kechiktirilgan signal bilan signal
{
sum = sum + ((((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] - signal va X [k+i] - kechiktirilgan versiya
}
autoCorr = sum / SAMPLES;
// First Peak Detect State Machine
agar (state_machine == 0 && i == 0)
{
o'rish = autoCorr * 0.5;
davlat mashinasi = 1;
}
aks holda (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, birinchi tsikldan foydalanish uchun 1 davrni toping.
{
maxValue = autoCorr ;
}
aks holda (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodBegin = i-1;
davlat mashinasi = 2;
numOfCycles = 1;
samplePerPeriod = (periodBegin - 0);
davr = samplePerPeriod;
sozlovchi = TUNER+(50.04 * exp (-0.102 * samplePerPeriod));
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-sozlovchi; // f = fs/N.
}
aks holda (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, 1 va 2 -tsikl uchun 2 davrni toping.
{
maxValue = autoCorr ;
}
aks holda (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
davlat mashinasi = 3;
numOfCycles = 2;
samplePerPeriod = (periodEnd - 0);
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-sozlovchi; // f = (2*fs)/(2*N)
maxValue = 0;
}
aks holda (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, 1, 2 va 3 -tsikl uchun 3 davrni toping.
{
maxValue = autoCorr ;
}
aks holda (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
davlat mashinasi = 4;
numOfCycles = 3;
samplePerPeriod = (periodEnd - 0);
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-sozlovchi; // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// Natijalarni tahlil qilish
//*****************************************************************
agar (samplePerPeriod == 0)
{
Serial.println ("Hmm ….. ishonchim komil emas. Siz meni aldashga harakat qilyapsizmi?");
}
boshqa
{
// tortish funktsiyasini tayyorlang
jami = 0;
agar (signalFrequency! = 0)
{
jami = 1;
}
agar (signalFrequency2! = 0)
{
jami = jami + 2;
}
agar (signalFrequency3! = 0)
{
jami = jami + 3;
}
// tortish funktsiyasi yordamida chastotani hisoblang
signalFrequencyGuess = ((1/total) * signalFrequency) + ((2/total) * signalFrequency2) + ((3/total) * signalFrekans3); // vaznli chastotani toping
Serial.print ("Siz o'ynagan eslatma taxminan");
Serial.print (signalFrequencyGuess); // Chastotani taxminini chop eting.
Serial.println ("Hz.");
// taxmin asosida oktava diapazonini toping
oktav oralig'i = 3;
while (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7))
{
uchun (i = 0; i <12; i ++)
{
storageNoteFreq = 2 * saqlanganNoteFreq ;
}
octaveRange ++;
}
// Eng yaqin eslatmani toping
minValue = 10000000;
noteLocation = 0;
uchun (i = 0; i <12; i ++)
{
if (minValue> abs (signalFrequencyGuess-storedNoteFreq )))
{
minValue = abs (signalFrequencyGuess-storedNoteFreq );
noteLocation = i;
}
}
// Eslatmani chop eting
Serial.print ("Menimcha, siz o'ynadingiz");
agar (noteLocation == 0)
{
Serial.print ("C");
}
boshqa bo'lsa (noteLocation == 1)
{
Serial.print ("C#");
}
boshqa bo'lsa (noteLocation == 2)
{
Serial.print ("D");
}
boshqa bo'lsa (noteLocation == 3)
{
Serial.print ("D#");
}
aks holda (noteLocation == 4)
{
Serial.print ("E");
}
boshqa bo'lsa (noteLocation == 5)
{
Serial.print ("F");
}
boshqa bo'lsa (noteLocation == 6)
{
Serial.print ("F#");
}
boshqa bo'lsa (noteLocation == 7)
{
Serial.print ("G");
}
boshqa bo'lsa (noteLocation == 8)
{
Serial.print ("G#");
}
boshqa bo'lsa (noteLocation == 9)
{
Serial.print ("A");
}
aks holda (noteLocation == 10)
{
Serial.print ("A#");
}
aks holda (noteLocation == 11)
{
Serial.print ("B");
}
Serial.println (octaveRange);
}
//*****************************************************************
//Bu yerda to'xtang. Qayta ishga tushirish uchun Arduino -ni qayta o'rnatish tugmasini bosing
//*****************************************************************
vaqt (1);
}

GitHub tomonidan ❤ joylashtirilgan rawgistfile1.txt faylini ko'rish

3 -qadam: Musiqiy notalar detektorini o'rnating

Arduino Uno -ni kompyuterga Arduino IDE -da yozilgan yoki yuklangan kod bilan ulang. Kodni tuzing va Arduino -ga yuklang. O'chirgichni musiqa manbasiga yaqin joylashtiring. Eslatma: Kirish videosida men musiqa manbai sifatida planshetga o'rnatilgan kompyuter dinamiklari bilan birgalikda ishlataman. Arduino kartasidagi reset tugmachasini bosing va keyin musiqa manbasida yozuvni o'ynating. Bir necha soniyadan so'ng Musiqiy notalar detektori ijro etilgan notani va uning chastotasini ko'rsatadi.

Tavsiya: