תוכן עניינים:

גלאי הערות מוסיקה Arduino: 3 שלבים
גלאי הערות מוסיקה Arduino: 3 שלבים

וִידֵאוֹ: גלאי הערות מוסיקה Arduino: 3 שלבים

וִידֵאוֹ: גלאי הערות מוסיקה Arduino: 3 שלבים
וִידֵאוֹ: ELF/EMBARC Bronchiectasis conference 2023 with subtitles 2024, יולי
Anonim
Image
Image

קשה לזהות תווי מוזיקה מאות השמע במיוחד בארדואינו בשל זיכרון מוגבל וכוח עיבוד. באופן כללי, הפתק אינו גל סינוס טהור המקשה על הגילוי. אם ניקח את שינוי התדרים של כלי נגינה שונים, הוא עשוי להכיל הרמוניות מרובות המבוססות על התו המושמע. לכל מכשיר שילוב ייחודי משלו של הרמוניות שונות. בקוד זה ניסיתי להכין תוכנית שיכולה לכסות כמה שיותר מכשירים. אתה יכול להפנות סרטון מצורף שבו ניסיתי לבדוק את סוגי הכלים השונים, סוגים שונים של טונים שנוצרו על ידי המקלדת ואפילו צליל קולי נבדקים. דיוק הזיהוי משתנה בין מכשיר למכשיר. עבור מכשיר כלשהו (כלומר פסנתר) בטווח מוגבל (200-500Hz) הוא מדויק, בעוד שלכל מכשיר יש דיוק נמוך (כלומר הרמוניקה).

קוד זה עושה שימוש בקוד FFT שפותח בעבר בשם EasyFFT.

הדגמת הקוד מוצגת בסרטון לעיל עם סוגים שונים של צלילי כלי וגם ווקאלי.

אספקה

- Arduino Nano/Uno או מעל

- מודול מיקרופון עבור Arduino

שלב 1: אלגוריתם לזיהוי הערות

כפי שצוין בשלב הקודם, הזיהוי קשה בשל הימצאותם של תדרים מרובים בדגימות השמע.

התוכנית פועלת בזרימה הבאה:

1. רכישת נתונים:

- סעיף זה לוקח 128 דוגמאות מנתוני שמע, ההפרדה בין שני דוגמאות (תדירות הדגימה) בהתאם לתדירות העניין. במקרה זה, אנו משתמשים במרווח בין שתי דגימות המשמש ליישום פונקציית חלון האן וכן חישוב משרעת/RMS. קוד זה גם מבצע אפס גס על ידי הפחתת 500 מהערך האנלוגי. ניתן לשנות ערך זה במידת הצורך. במקרה טיפוסי, ערכים אלה עובדים היטב. יתר על כן, יש להוסיף עיכוב כלשהו כדי שתדירות הדגימה תהיה סביב 1200 הרץ. במקרה של תדר דגימה של 1200 הרץ ניתן לזהות מקסימום של תדר 600 הרץ.

עבור (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // סכום משמרת אפס גס 1 = סכום 1+a; // לערך ממוצע sum2 = sum2+a*a; // לערך RMS a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // חלון האן ב = 4*א; // קנה מידה עבור עיכוב המרה של float to int MicroSeconds (195); // מבוסס על טווח תדרי הפעולה}

2. FFT:

לאחר שהנתונים מוכנים, FFT מבוצע באמצעות EasyFFT. פונקציית EasyFFT זו שונה לתיקון FFT עבור 128 דגימות. הקוד שונה גם כדי להפחית את צריכת הזיכרון. הפונקציה המקורית EasyFFT שנועדה להכיל עד 1028 דוגמאות (עם הלוח התואם), בעוד שאנחנו צריכים רק 128 דוגמאות. קוד זה מפחית את צריכת הזיכרון בכ -20% בהשוואה לפונקציית EasyFFT המקורית.

לאחר סיום ה- FFT, הקוד מחזיר את 5 פסגות התדרים הדומיננטיות ביותר לניתוח נוסף. תדר זה מסודר בסדר משרעת יורד.

3. עבור כל שיא, הקוד מזהה הערות אפשריות הקשורות אליו. קוד זה סורק עד 1200 הרץ בלבד. אין צורך לשים לב לתדירות עם משרעת מרבית.

כל התדרים ממופים בין 0 ל -255, כאן האוקטבה הראשונה מזוהה, למשל, 65.4 הרץ עד 130.8 מייצגים אוקטבה אחת, 130.8 הרץ עד 261.6 הרץ מייצג אחר. עבור כל אוקטבה, התדרים ממופים מ- 0 עד 255. כאן המיפוי החל מ- C ל- C '.

אם (f_peaks > 1040) {f_peaks = 0;} if (f_peaks > = 65.4 && f_peaks = 130.8 && f_peaks = 261.6 && f_peaks = 523.25 && f_peaks = 1046 && f_peaks <= 2093) {f_peaks = 255*((f_peaks /1046) -1);}

ערכי מערך NoteV משמשים להקצאת הפתק לתדרים שזוהו.

בייט NoteV [13] = {8, 23, 40, 57, 76, 96, 116, 138, 162, 187, 213, 241, 255};

4. לאחר חישוב הערה לכל תדר יתכן כי קיימים תדרים מרובים המעידים על אותה תו. כדי לקבל קוד פלט מדויק שוקל גם חזרות. הקוד מוסיף את כל ערכי התדר המבוססים על סדר משרעת וחזרות ומציין את הפתק במשרעת מרבית.

שלב 2: יישום

השימוש בקוד הוא פשוט, עם זאת, יש גם מספר מגבלות שצריך לזכור בזמן זה. ניתן להעתיק את הקוד כפי שהוא משמש לזיהוי פתקים. יש לקחת בחשבון את הנקודות שלהלן בעת השימוש בה.

1. הקצאת סיכה:

על פי הקצאת הסיכה המצורפת יש לשנות. לניסוי שלי שמרתי אותו על סיכה אנלוגית 7, הגדרת חלל () {Serial.begin (250000); Mic_pin = A7; }

2. רגישות למיקרופון:

צריך לשנות את הרגישות למיקרופון ניתן ליצור צורת גל כזו עם משרעת טובה. לרוב, מודול המיקרופון מגיע עם הגדרת רגישות. רגישות מתאימה להיבחר כך שהאות לא קטן מדי וגם לא מתנתק בגלל משרעת גבוהה יותר.

3. סף משרעת:

קוד זה מופעל רק אם משרעת האות גבוהה מספיק. הגדרה זו צריכה להיות מוגדרת באופן ידני על ידי המשתמש. ערך זה תלוי ברגישות המיקרופון כמו גם ביישום.

אם (sum2-sum1> 5) {

..

בקוד לעיל, sum2 נותן ערך RMS ואילו סכום 1 נותן ערך ממוצע. כך שההבדל בין שני ערכים אלה נותן את משרעת אות הקול. במקרה שלי, זה עובד כראוי עם ערך משרעת של בערך 5.

4. כברירת מחדל, קוד זה ידפיס את הפתק שזוהה. עם זאת, אם אתה מתכנן להשתמש בפתק למטרה אחרת, יש להשתמש במספר שהוקצה ישירות. למשל C = 0; C#= 1, D = 2, D#= 3 ואילך.

5. אם המכשיר בעל תדר גבוה יותר, הקוד עשוי לתת פלט שווא. התדירות המרבית מוגבלת על ידי תדירות הדגימה. כך שתוכל לשחק מתחת לערכי עיכוב כדי להשיג תפוקה אופטימלית. בעיכוב הקוד למטה של 195 מיקרו שניות. אשר עשוי להיות משופץ כדי לקבל תפוקה אופטימלית. זה ישפיע על זמן הביצוע הכולל.

{a = analogRead (Mic_pin) -500; // משמרת אפס גסה

סכום 1 = סכום 1+a; // לערך ממוצע sum2 = sum2+a*a; // לערך RMS a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // חלון האן ב = 4*א; // קנה מידה עבור עיכוב ההמרה של float to intMicroseconds (195); // מבוסס על טווח תדרי הפעולה}

6. קוד זה יפעל רק עד תדר 2000 הרץ. על ידי ביטול העיכוב בין הדגימה סביב 3-4 קילוהרץ של תדרי הדגימה ניתן להשיג.

אמצעי זהירות:

  • כפי שצוין במדריך EasyFFT, ה- FFT אוכל כמות עצומה של זיכרון של Arduino. אז אם יש לך תוכנית שצריך לאחסן כמה ערכים מומלץ להשתמש בלוח בעל זיכרון גבוה יותר.
  • קוד זה עשוי לפעול היטב עבור כלי/סולן אחד ופחות רע אחר. לא ניתן לזהות בזמן אמת מדויק בשל מגבלות חישוביות.

שלב 3: קיצי

זיהוי הערות הוא עבודה אינטנסיבית מבחינה חישובית, קבלת תפוקה בזמן אמת קשה מאוד במיוחד על Arduino. קוד זה יכול לתת בסביבות 6.6 דוגמאות /שניות (עבור הוספת עיכוב של 195 מיקרו שניות). קוד זה עובד היטב עם הפסנתר וכמה כלים אחרים.

אני מקווה שהקוד והמדריך הזה יעזרו בפרויקט שלך הקשור למוזיקה. במקרה של ספק או הצעה אל תהסס להגיב או לשלוח הודעה.

במדריך הקרוב, אשנה את הקוד הזה לזיהוי אקורדי מוזיקה. אז הישאר מעודכן.

מוּמלָץ: