Სარჩევი:

მუსიკალური ნოტების დეტექტორი: 3 ნაბიჯი
მუსიკალური ნოტების დეტექტორი: 3 ნაბიჯი

ვიდეო: მუსიკალური ნოტების დეტექტორი: 3 ნაბიჯი

ვიდეო: მუსიკალური ნოტების დეტექტორი: 3 ნაბიჯი
ვიდეო: ლუკა და მარიამი 2024, ნოემბერი
Anonim
Image
Image

გააოცეთ თქვენი მეგობრები და ოჯახი ამ პროექტით, რომელიც ამოიცნობს ინსტრუმენტის მიერ შესრულებულ ნოტს. ეს პროექტი აჩვენებს სავარაუდო სიხშირეს, ასევე მუსიკალურ ნოტს, რომელიც უკრავს ელექტრონულ კლავიატურაზე, ფორტეპიანოზე ან ნებისმიერ სხვა ინსტრუმენტზე.

დეტალები

ამ პროექტისთვის, ხმის მოდულის დეტექტორიდან ანალოგური გამომავალი იგზავნება Arduino Uno– ს A0 ანალოგიურ შეყვანაზე. ანალოგური სიგნალის შერჩევა და კვანტირება (დიგიტალიზაცია). ავტოკორელაცია, აწონვა და დარეგულირების კოდი გამოიყენება ფუნდამენტური სიხშირის დასადგენად პირველი 3 პერიოდის გამოყენებით. შემდეგ სავარაუდო ფუნდამენტური სიხშირე შედარებულია ოქტავების 3, 4 და 5 დიაპაზონის სიხშირეებთან, რათა დადგინდეს უახლოესი მუსიკალური ნოტების სიხშირე. ბოლოს უახლოესი სიხშირის სავარაუდო შენიშვნა იბეჭდება ეკრანზე.

შენიშვნა: ეს ინსტრუქცია მხოლოდ ყურადღებას ამახვილებს იმაზე, თუ როგორ უნდა ავაშენოთ პროექტი. დეტალების და დიზაინის დასაბუთების შესახებ დამატებითი ინფორმაციისათვის ეწვიეთ ამ ბმულს: დამატებითი ინფორმაცია

მარაგები

  • (1) Arduino Uno (ან Genuino Uno)
  • (1) DEVMO მიკროფონის სენსორი მაღალი მგრძნობელობის ხმის გამოვლენის მოდული თავსებადია
  • (1) Solderless Breadboard
  • (1) USB-A to B კაბელი
  • ჯუმბერის მავთულები
  • მუსიკალური წყარო (ფორტეპიანო, კლავიატურა ან ტკივილის პროგრამა დინამიკებით)
  • (1) კომპიუტერი ან ლეპტოპი

ნაბიჯი 1: აპარატურის შექმნა მუსიკალური ჩანაწერების დეტექტორისთვის

დააყენეთ მუსიკალური შენიშვნების დეტექტორი
დააყენეთ მუსიკალური შენიშვნების დეტექტორი

Arduino Uno– ს გამოყენებით, დამაკავშირებელი მავთულები, გამჭვირვალე დაფა და DEVMO მიკროფონის სენსორი მაღალი მგრძნობელობის ხმის გამოვლენის მოდული (ან მსგავსი) ააშენეთ ამ სურათზე ნაჩვენები წრე

ნაბიჯი 2: პროგრამირება მუსიკალური შენიშვნების დეტექტორი

Arduino IDE– ში დაამატეთ შემდეგი კოდი.

gistfile1.txt

/*
ფაილის/ესკიზის სახელი: MusicalNoteDetector
ვერსია No.: v1.0 შექმნილია 2020 წლის 7 ივნისი
ორიგინალური ავტორი: Clyde A. Lettsome, PhD, PE, MEM
აღწერა: ეს კოდი/ესკიზი აჩვენებს სავარაუდო სიხშირეს, ასევე მუსიკალურ ნოტს, რომელიც უკრავს ელექტრონულ კლავიატურაზე ან ფორტეპიანოზე. ამ პროექტისთვის, ანალოგური გამომავალი
ხმის მოდულის დეტექტორი იგზავნება Arduino Uno– ს A0 ანალოგიურ შეყვანაზე. ანალოგური სიგნალის შერჩევა და კვანტირება (დიგიტალიზაცია). გამოიყენება ავტოკორელაცია, აწონვა და დარეგულირების კოდი
იპოვეთ ფუნდამენტური სიხშირე პირველი 3 პერიოდის გამოყენებით. სავარაუდო ფუნდამენტური სიხშირე ადარებს სიხშირეებს ოქტავებში 3, 4 და 5 დიაპაზონში, რათა დადგინდეს უახლოესი მუსიკალური
შენიშვნის სიხშირე. ბოლოს უახლოესი სიხშირის სავარაუდო შენიშვნა იბეჭდება ეკრანზე.
ლიცენზია: ეს პროგრამა არის უფასო პროგრამული უზრუნველყოფა; შეგიძლიათ გადაანაწილოთ იგი და/ან შეცვალოთ იგი GNU ზოგადი საჯარო ლიცენზიის (GPL) ვერსიის 3 ან უფრო გვიან
თქვენი არჩევანის ვერსია, როგორც გამოქვეყნებულია თავისუფალი პროგრამული უზრუნველყოფის ფონდის მიერ.
შენიშვნები: საავტორო უფლება (გ) 2020 C. A Lettsome Services, LLC
დამატებითი ინფორმაციისთვის ეწვიეთ
*/
#განსაზღვრეთ SAMPLES 128 // Max 128 Arduino Uno– სთვის.
#განსაზღვრეთ SAMPLING_FREQUENCY 2048 // Fs = Nyquist- ის საფუძველზე, უნდა იყოს 2 -ჯერ ყველაზე მაღალი მოსალოდნელი სიხშირე.
#განსაზღვრეთ OFFSETSAMPLES 40 // გამოიყენება საკლაბრაციო მიზნებისთვის
#define TUNER -3 // მორგება სანამ C3 არის 130.50
float sampling პერიოდი;
ხელმოუწერელი გრძელი მიკროწამი;
int X [SAMPLES]; // შექმნა SEMPLES- ის ზომის ვექტორი რეალური მნიშვნელობების შესანარჩუნებლად
float autoCorr [SAMPLES]; // შექმენით ნიმუშების ვექტორი წარმოსახვითი მნიშვნელობების შესანარჩუნებლად
float storageNoteFreq [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]; // ოფსეტური ვექტორის შექმნა
int avgOffSet; // ოფსეტური ვექტორის შექმნა
int i, k, periodEnd, periodBegin, period, adjustuster, noteLocation, octaveRange;
float maxValue, minValue;
გრძელი თანხა;
int thresh = 0;
int numOfCycles = 0;
float სიგნალი სიხშირე, სიგნალი სიხშირე 2, სიგნალი სიხშირე 3, სიგნალი სიხშირე გამოიცანი, სულ;
ბაიტი state_machine = 0;
int ნიმუშები პერიოდი = 0;
ბათილად დაყენება ()
{
Serial.begin (115200); // 115200 Baud განაკვეთი სერიული მონიტორისთვის
}
ბათილი მარყუჟი ()
{
//*****************************************************************
// კალაბერაციის განყოფილება
//*****************************************************************
Serial.println ("კალაბრაცია. გთხოვთ, კალათბურთის დროს ნუ შეასრულებთ ნოტებს.");
for (i = 0; i <OFFSETSAMPLES; i ++)
{
offSet = analogRead (0); // კითხულობს მნიშვნელობას ანალოგური პინიდან 0 (A0), ადგენს მას რაოდენობრივად და ინახავს მას როგორც ნამდვილ ტერმინს.
//Serial.println(offSet ); // გამოიყენეთ ეს ხმის გამოვლენის მოდულის შესაცვლელად დაახლოებით ნახევარზე ან 512 -ზე, როდესაც ხმა არ უკრავს.
sumOffSet = sumOffSet + offSet ;
}
samplePerPeriod = 0;
maxValue = 0;
//*****************************************************************
// მოემზადეთ A0– დან შეყვანის მისაღებად
//*****************************************************************
avgOffSet = მრგვალი (sumOffSet / OFFSETSAMPLES);
Serial.println ("ითვლიან.");
დაგვიანება (1000); // პაუზა 1 წამის განმავლობაში
Serial.println ("3");
დაგვიანება (1000); // პაუზა 1 წამის განმავლობაში
Serial.println ("2");
დაგვიანება (1000); // პაუზა 1
Serial.println ("1");
დაგვიანება (1000); // პაუზა 1 წამის განმავლობაში
Serial.println ("ითამაშეთ თქვენი შენიშვნა!");
დაგვიანება (250); // გააჩერეთ 1/4 წამი რეაქციის დროზე
//*****************************************************************
// შეაგროვეთ ნიმუშები A0– დან ნიმუშის აღების პერიოდი
//*****************************************************************
შერჩევის პერიოდი = 1.0 / SAMPLING_FREQUENCY; // პერიოდი მიკროწამებში
for (i = 0; i <SAMPLES; i ++)
{
microSeconds = micros (); // აბრუნებს მიკროწამების რაოდენობას მას შემდეგ რაც Arduino დაფამ დაიწყო მიმდინარე სკრიპტის გაშვება.
X = analogRead (0); // კითხულობს მნიშვნელობას ანალოგური პინიდან 0 (A0), ადგენს მას რაოდენობრივად და ინახავს მას როგორც ნამდვილ ტერმინს.
/ *დარჩენილი ლოდინის დრო ნიმუშებს შორის საჭიროების შემთხვევაში წამებში */
ხოლო (micros () <(microSeconds + (samplingPeriod * 1000000)))
{
// არაფერი გააკეთო უბრალოდ დაელოდე
}
}
//*****************************************************************
// ავტოკორელაციის ფუნქცია
//*****************************************************************
for (i = 0; i <SAMPLES; i ++) // i = დაგვიანებით
{
ჯამი = 0;
for (k = 0; k <SAMPLES - i; k ++) // ემთხვევა სიგნალს დაგვიანებულ სიგნალთან
{
თანხა = თანხა + ((((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] არის სიგნალი და X [k+i] არის დაგვიანებული ვერსია
}
autoCorr = თანხა / ნიმუშები;
// First Peak Detect State Machine
თუ (state_machine == 0 && i == 0)
{
thresh = autoCorr * 0.5;
სახელმწიფო_ მანქანა = 1;
}
წინააღმდეგ შემთხვევაში, თუ (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, იპოვეთ 1 პერიოდი პირველი ციკლის გამოყენებისათვის
{
maxValue = autoCorr ;
}
წინააღმდეგ შემთხვევაში, თუ (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
პერიოდი დასაწყისი = i-1;
სახელმწიფო_ მანქანა = 2;
numOfCycles = 1;
samplePerPeriod = (პერიოდი დასაწყისი - 0);
პერიოდი = samplePerPeriod;
მარეგულირებელი = TUNER+(50.04 * exp (-0.102 * samplePerPeriod));
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-რეგულირებადი; // f = fs/N
}
წინააღმდეგ შემთხვევაში, თუ (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, იპოვეთ 2 პერიოდი 1 და 2 ციკლისთვის
{
maxValue = autoCorr ;
}
წინააღმდეგ შემთხვევაში, თუ (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
პერიოდი დასასრული = i-1;
სახელმწიფო_ მანქანა = 3;
numOfCycles = 2;
samplePerPeriod = (პერიოდი დასასრული - 0);
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-მორგება; // f = (2*fs)/(2*N)
maxValue = 0;
}
წინააღმდეგ შემთხვევაში, თუ (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, იპოვეთ 3 პერიოდი 1, 2 და 3 ციკლისთვის
{
maxValue = autoCorr ;
}
წინააღმდეგ შემთხვევაში, თუ (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
პერიოდი დასასრული = i-1;
სახელმწიფო_ მანქანა = 4;
numOfCycles = 3;
samplePerPeriod = (პერიოდი დასასრული - 0);
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-მორგება; // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// შედეგების ანალიზი
//*****************************************************************
თუ (samplePerPeriod == 0)
{
Serial.println ("ჰმ ….. არ ვარ დარწმუნებული. ცდილობ ჩემს მოტყუებას?");
}
სხვა
{
// წონის ფუნქციის მომზადება
სულ = 0;
თუ (სიგნალის სიხშირე! = 0)
{
სულ = 1;
}
თუ (სიგნალი სიხშირე 2! = 0)
{
სულ = სულ + 2;
}
თუ (სიგნალი სიხშირე 3! = 0)
{
სულ = სულ +3;
}
// გამოთვალეთ სიხშირე შეწონილი ფუნქციის გამოყენებით
signalFrequencyGuess = ((1/სულ) * signalFrequency) + ((2/სულ) * signalFrequency2) + ((3/სულ) * signalFrequency3); // იპოვეთ შეწონილი სიხშირე
Serial.print ("შენიშვნა, რომელიც თქვენ ითამაშეთ არის დაახლოებით");
Serial.print (signalFrequencyGuess); // დაბეჭდე სიხშირის გამოცნობა.
Serial.println ("ჰზ.");
// იპოვეთ ოქტავის დიაპაზონი ვარაუდის საფუძველზე
octaveRange = 3;
ხოლო (! (signalFrequencyGuess> = შენახული NotFreq [0] -7 && სიგნალი FrequencyGuess <= შენახული NotFreq [11] +7))
{
for (i = 0; i <12; i ++)
{
შენახული NoteFreq = 2 * შენახული NoteFreq ;
}
octaveRange ++;
}
// იპოვეთ უახლოესი შენიშვნა
minValue = 10000000;
noteLocation = 0;
for (i = 0; i <12; i ++)
{
if (minValue> abs (signalFrequencyGuess-storageNoteFreq )))
{
minValue = abs (signalFrequencyGuess-storageNoteFreq );
noteLocation = i;
}
}
// დაბეჭდეთ შენიშვნა
Serial.print ("მე მგონი შენ თამაშობდი");
თუ (noteLocation == 0)
{
Serial.print ("C");
}
სხვა შემთხვევაში (noteLocation == 1)
{
Serial.print ("C#");
}
სხვა შემთხვევაში (noteLocation == 2)
{
Serial.print ("D");
}
სხვა შემთხვევაში (noteLocation == 3)
{
Serial.print ("D#");
}
სხვა შემთხვევაში თუ (შენიშვნა მდებარეობა == 4)
{
Serial.print ("E");
}
სხვა შემთხვევაში (შენიშვნა ლოკაცია == 5)
{
Serial.print ("F");
}
სხვა შემთხვევაში თუ (შენიშვნა მდებარეობა == 6)
{
Serial.print ("F#");
}
სხვა შემთხვევაში (შენიშვნა ლოკაცია == 7)
{
Serial.print ("G");
}
სხვა შემთხვევაში თუ (შენიშვნა მდებარეობა == 8)
{
Serial.print ("G#");
}
სხვა შემთხვევაში თუ (შენიშვნა მდებარეობა == 9)
{
Serial.print ("A");
}
სხვა შემთხვევაში (შენიშვნა ლოკაცია == 10)
{
Serial.print ("A#");
}
სხვა შემთხვევაში (შენიშვნა ლოკაცია == 11)
{
Serial.print ("B");
}
Serial.println (octaveRange);
}
//*****************************************************************
//Აქ გაჩერდი. გადატვირთვისთვის დააჭირეთ Arduino– ს გადატვირთვის ღილაკს
//*****************************************************************
ხოლო (1);
}

rawgistfile1.txt– ის ნახვა GitHub– ით

ნაბიჯი 3: დააყენეთ მუსიკალური შენიშვნების დეტექტორი

დაუკავშირეთ Arduino Uno კომპიუტერს Arduino IDE- ში ჩაწერილი ან ჩატვირთული კოდით. შეადგინეთ და ატვირთეთ კოდი არდუინოში. მოათავსეთ წრე მუსიკის წყაროსთან ახლოს. შენიშვნა: შესავალი ვიდეო, მე ვიყენებ ტაბლეტზე დაინსტალირებულ პროგრამას კომპიუტერის დინამიკებთან ერთად, როგორც ჩემი მუსიკის წყაროს. დააჭირეთ Arduino დაფაზე გადატვირთვის ღილაკს და შემდეგ ჩაწერეთ ჩანაწერი მუსიკის წყაროზე. რამდენიმე წამის შემდეგ, მუსიკალური შენიშვნების დეტექტორი აჩვენებს დაკვრის ნოტს და მის სიხშირეს.

გირჩევთ: