فهرست مطالب:

آشکارساز نت موسیقی: 3 مرحله
آشکارساز نت موسیقی: 3 مرحله

تصویری: آشکارساز نت موسیقی: 3 مرحله

تصویری: آشکارساز نت موسیقی: 3 مرحله
تصویری: جایگاه نت ها روی دسته سه تار 2024, نوامبر
Anonim
Image
Image

با این پروژه که نت های نواخته شده توسط یک ساز را تشخیص می دهد ، دوستان و خانواده خود را شگفت زده کنید. این پروژه فرکانس تقریبی و همچنین نت موسیقی را که روی صفحه کلید الکترونیکی ، برنامه پیانو یا هر ساز دیگر پخش می شود نشان می دهد.

جزئیات

برای این پروژه ، خروجی آنالوگ از آشکارساز ماژول صدا به ورودی آنالوگ A0 Arduino Uno ارسال می شود. سیگنال آنالوگ نمونه برداری و کمی سازی (دیجیتالی) می شود. برای یافتن فرکانس اساسی با استفاده از 3 دوره اول ، از کد خود همبستگی ، وزن و تنظیم استفاده می شود. فرکانس اصلی تقریبی سپس با فرکانس های محدوده اکتاو 3 ، 4 و 5 مقایسه می شود تا نزدیکترین فرکانس نت موسیقی مشخص شود. در نهایت یادداشت حدس زده شده برای نزدیکترین فرکانس روی صفحه چاپ می شود.

توجه: این دستورالعمل فقط بر نحوه ساخت پروژه تمرکز دارد. برای اطلاعات بیشتر در مورد جزئیات و توجیهات طراحی ، لطفاً از این پیوند دیدن کنید: اطلاعات بیشتر

تدارکات

  • (1) Arduino Uno (یا Genuino Uno)
  • (1) سنسور میکروفن DEVMO ماژول تشخیص صدا با حساسیت بالا سازگار است
  • (1) تخته نان بدون جوش
  • (1) کابل USB-A تا B
  • سیم های بلوز
  • منبع موسیقی (پیانو ، صفحه کلید یا برنامه درد با بلندگوها)
  • (1) کامپیوتر یا لپ تاپ

مرحله 1: سخت افزار را برای آشکارساز یادداشت موسیقی بسازید

آشکارساز یادداشت موسیقی را راه اندازی کنید
آشکارساز یادداشت موسیقی را راه اندازی کنید

با استفاده از Arduino Uno ، سیم های اتصال ، یک تخته نان بدون لحیم و یک ماژول تشخیص صدا با حساسیت میکروفون DEVMO (یا مشابه) مدار نشان داده شده در این تصویر را ایجاد کنید

مرحله 2: برنامه آشکارساز موسیقی را برنامه ریزی کنید

در Arduino IDE کد زیر را اضافه کنید.

gistfile1.txt

/*
نام فایل/طرح: MusicalNoteDetector
نسخه شماره: v1.0 ایجاد شده در 7 ژوئن 2020
نویسنده اصلی: Clyde A. Lettsome ، PhD ، PE ، MEM
توضیحات: این کد/طرح فرکانس تقریبی و همچنین نت موسیقی پخش شده بر روی صفحه کلید الکترونیکی یا برنامه پیانو را نشان می دهد. برای این پروژه ، خروجی آنالوگ از
آشکارساز ماژول صدا به ورودی آنالوگ A0 آردوینو Uno ارسال می شود. سیگنال آنالوگ نمونه برداری و کمی سازی (دیجیتالی) می شود. همبستگی خودکار ، وزن و تنظیم کد مورد استفاده قرار می گیرد
فرکانس اساسی را با استفاده از 3 دوره اول پیدا کنید. فرکانس بنیادی تقریبی سپس با فرکانسهای محدوده اکتاو 3 ، 4 و 5 مقایسه می شود تا نزدیکترین موزیکال تعیین شود.
فرکانس یادداشت در نهایت یادداشت حدس زده شده برای نزدیکترین فرکانس روی صفحه چاپ می شود.
مجوز: این برنامه یک نرم افزار رایگان است. می توانید آن را مجدداً توزیع کرده و/یا تحت شرایط مجوز عمومی GNU (GPL) نسخه 3 یا نسخه های بعدی تغییر دهید
نسخه انتخابی شما ، همانطور که توسط بنیاد نرم افزار آزاد منتشر شده است.
یادداشت ها: حق چاپ (ج) 2020 توسط C. A. Lettsome Services، LLC
برای اطلاعات بیشتر به https://clydelettsome.com/blog/2020/06/07/my-weekend-project-musical-note-detector-using-an-arduino/ مراجعه کنید
*/
#تعریف نمونه 128 /حداکثر 128 برای Arduino Uno.
#تعریف SAMPLING_FREQUENCY 2048 // Fs = بر اساس Nyquist ، باید 2 برابر بیشترین فرکانس مورد انتظار باشد.
#تعریف OFFSETSAMPLES 40 // برای مقاصد مورد استفاده قرار می گیرد
#define TUNER -3 // تنظیم کنید تا C3 130.50 شود
نمونه برداری شناور دوره
میکرو ثانیه های طولانی بدون علامت ؛
int X [نمونه] ؛ // ایجاد بردار اندازه SAMPLES برای نگه داشتن مقادیر واقعی
floot autoCorr [SAMPLES] ؛ // ایجاد بردار اندازه 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، تنظیم کننده، noteLocation، octaveRange؛
float maxValue ، minValue ؛
مبلغ طولانی ؛
int thresh = 0؛
int numOfCycles = 0 ؛
سیگنال شناور فرکانس ، سیگنال فرکانس 2 ، سیگنال فرکانس 3 ، سیگنال فرکانس حدس زدن ، مجموع ؛
بایت state_machine = 0؛
نمونه intPerPeriod = 0 ؛
void setup ()
{
Serial.begin (115200) ؛ // 115200 نرخ Baud برای سریال مانیتور
}
حلقه خالی ()
{
//*****************************************************************
// بخش Calabration
//*****************************************************************
Serial.println ("Calabrating. لطفاً در هنگام calabration هیچ نت را پخش نکنید.")؛
برای (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 ثانیه مکث کنید
//*****************************************************************
// نمونه SAMPLES از A0 را با دوره نمونه گیری SamplingPeriod جمع آوری کنید
//*****************************************************************
samplingPeriod = 1.0 / SAMPLING_FREQUENCY ؛ // دوره بر حسب میکروثانیه
برای (i = 0 ؛ i <SAMPLES ؛ i ++)
{
microSeconds = micros ()؛ // تعداد میکرو ثانیه ها را از زمانی که برد آردوینو شروع به اجرای اسکریپت فعلی می کند ، برمی گرداند.
X = analogRead (0) ؛ // مقدار را از پین آنالوگ 0 (A0) می خواند ، آن را کمی می کند و به عنوان یک عبارت واقعی ذخیره می کند.
/ *زمان انتظار بین نمونه ها در صورت لزوم در ثانیه */
در حالی که (micros () <(microSeconds + (samplingPeriod * 1000000)))
{
// هیچ کاری نکن فقط صبر کن
}
}
//*****************************************************************
// تابع خود همبستگی
//*****************************************************************
برای (i = 0 ؛ i <SAMPLES ؛ i ++) // i = تأخیر
{
جمع = 0 ؛
برای (k = 0 ؛ k <SAMPLES - i ؛ k ++) // سیگنال را با سیگنال تأخیری مطابقت دهید
{
sum = sum + ((((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)) ؛ // X [k] سیگنال و X [k+i] نسخه تاخیری است
}
autoCorr = sum / SAMPLES؛
// First Peak Detect Machine State
if (state_machine == 0 && i == 0)
{
thresh = autoCorr * 0.5 ؛
state_machine = 1؛
}
در غیر این صورت (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1 ، 1 دوره برای استفاده از چرخه اول پیدا کنید
{
maxValue = autoCorr ؛
}
else if (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodBegin = i-1؛
state_machine = 2؛
numOfCycles = 1 ؛
samplePerPeriod = (periodBegin - 0)؛
period = 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 ؛
}
else if (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1؛
state_machine = 3؛
numOfCycles = 2 ؛
samplePerPeriod = (periodEnd - 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 ؛
}
else 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 ؛
samplePerPeriod = (periodEnd - 0)؛
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-تنظیم کننده ؛ // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// تجزیه و تحلیل نتایج
//*****************************************************************
if (samplePerPeriod == 0)
{
Serial.println ("هوم ….. من مطمئن نیستم. آیا سعی می کنید مرا فریب دهید؟")؛
}
دیگری
{
// تابع وزنه را آماده کنید
مجموع = 0 ؛
if (signalFrequency! = 0)
{
مجموع = 1 ؛
}
if (signalFrequency2! = 0)
{
مجموع = مجموع + 2؛
}
if (signalFrequency3! = 0)
{
مجموع = مجموع + 3؛
}
// فرکانس را با استفاده از تابع وزنی محاسبه کنید
signalFrequencyGuess = ((1/مجموع) * signalFrequency) + ((2/مجموع) * signalFrequency2) + ((3/مجموع) * signalFrequency3)؛ // فرکانس وزنی را بیابید
Serial.print ("یادداشتی که بازی کرده اید تقریبا") ؛
Serial.print (signalFrequencyGuess) ؛ // حدس فرکانس را چاپ کنید.
Serial.println ("هرتز") ؛
// بر اساس حدس محدوده اکتاو را پیدا کنید
octaveRange = 3 ؛
while (! (signalFrequencyGuess> = storageNoteFreq [0] -7 && signalFrequencyGuess <= storageNoteFreq [11] +7))
{
برای (i = 0 ؛ i <12؛ i ++)
{
storageNoteFreq = 2 * storageNoteFreq ؛
}
octaveRange ++؛
}
// نزدیکترین یادداشت را پیدا کنید
minValue = 10000000 ؛
noteLocation = 0؛
برای (i = 0 ؛ i <12؛ i ++)
{
if (minValue> abs (signalFrequencyGuess-storageNoteFreq )))
{
minValue = abs (signalFrequencyGuess-storageNoteFreq ) ؛
noteLocation = i؛
}
}
// چاپ یادداشت
Serial.print ("فکر کنم بازی کردی")؛
if (noteLocation == 0)
{
Serial.print ("C") ؛
}
else if (noteLocation == 1)
{
Serial.print ("C#")؛
}
else if (noteLocation == 2)
{
Serial.print ("D") ؛
}
else if (noteLocation == 3)
{
Serial.print ("D#")؛
}
else if (noteLocation == 4)
{
Serial.print ("E") ؛
}
else if (noteLocation == 5)
{
Serial.print ("F") ؛
}
else if (noteLocation == 6)
{
Serial.print ("F#")؛
}
else if (noteLocation == 7)
{
Serial.print ("G") ؛
}
else if (noteLocation == 8)
{
Serial.print ("G#") ؛
}
else if (noteLocation == 9)
{
Serial.print ("A") ؛
}
else if (noteLocation == 10)
{
Serial.print ("A#")؛
}
else if (noteLocation == 11)
{
Serial.print ("B") ؛
}
Serial.println (octaveRange) ؛
}
//*****************************************************************
// اینجا متوقف شوید. برای راه اندازی مجدد ، دکمه تنظیم مجدد را در Arduino فشار دهید
//*****************************************************************
در حالی که (1) ؛
}

view rawgistfile1.txt با ❤ توسط GitHub میزبانی شده است

مرحله 3: آشکارساز یادداشت موسیقی را راه اندازی کنید

Arduino Uno را با کد نوشته شده یا بارگذاری شده در Arduino IDE به رایانه وصل کنید. کد را در آردوینو کامپایل و بارگذاری کنید. مدار را نزدیک منبع موسیقی قرار دهید. توجه: در ویدئوی مقدماتی ، من از یک برنامه نصب شده روی رایانه لوحی همراه با بلندگوهای رایانه به عنوان منبع موسیقی خود استفاده می کنم. دکمه تنظیم مجدد در برد آردوینو را فشار دهید و سپس یک یادداشت را در منبع موسیقی پخش کنید. پس از چند ثانیه ، Musical Note Detector نت پخش شده و فرکانس آن را نمایش می دهد.

توصیه شده: