Բովանդակություն:

Arduino Music Notes Detector: 3 քայլ
Arduino Music Notes Detector: 3 քայլ

Video: Arduino Music Notes Detector: 3 քայլ

Video: Arduino Music Notes Detector: 3 քայլ
Video: 3 Options for Playing Audio on Arduino 2024, Դեկտեմբեր
Anonim
Image
Image

Ձայնային ազդանշանից երաժշտական նոտաներ հայտնաբերելը դժվար է անել հատկապես Arduino- ում `սահմանափակ հիշողության և մշակման հզորության պատճառով: Ընդհանրապես, նշումը մաքուր սինուս ալիք չէ, որը դժվարացնում է հայտնաբերումը: Եթե վերցնենք տարբեր երաժշտական գործիքների հաճախականությունների փոխակերպումը, այն կարող է պարունակել բազմաթիվ ներդաշնակություններ ՝ հիմնված նվագարկվող նոտայի վրա: Յուրաքանչյուր գործիք ունի տարբեր ներդաշնակության իր ստորագրության համադրությունը: Այս ծածկագրում ես փորձեցի կազմել ծրագիր, որը կարող է հնարավորինս շատ գործիքներ ընդգրկել: Կարող եք անդրադառնալ կցված տեսանյութին, որտեղ ես փորձել եմ ստուգել տարբեր տեսակի գործիքներ, ստեղնաշարի ստեղծած տարբեր տիպեր և նույնիսկ վոկալի ձայնը ստուգվում են: Հայտնաբերման ճշգրտությունը տարբերվում է գործիքներից գործիքի վրա: Սահմանափակ տիրույթում (200-500 Հց) որոշ գործիքի (այսինքն ՝ դաշնամուրի) համար այն ճշգրիտ է, իսկ որոշ գործիքների մոտ ՝ ցածր ճշգրտություն (այսինքն ՝ ներդաշնակ):

Այս ծածկագիրը օգտագործում է նախկինում մշակված FFT ծածկագիրը, որը կոչվում է EasyFFT:

Կոդի ցուցադրումը ցուցադրվում է վերը նշված տեսանյութում ՝ տարբեր տեսակի գործիքային ձայնով, ինչպես նաև վոկալով:

Պարագաներ

- Arduino Nano/Uno կամ ավելի բարձր

- Խոսափողի մոդուլ Arduino- ի համար

Քայլ 1. Նշումների հայտնաբերման ալգորիթմ

Ինչպես նշվեց նախորդ քայլում, հայտնաբերումը դժվար է աուդիո նմուշներում բազմաթիվ հաճախականությունների առկայության պատճառով:

Րագիրը գործում է հետևյալ ընթացքով.

1. Տվյալների ձեռքբերում.

- այս բաժինը վերցնում է աուդիո տվյալների 128 նմուշ, երկու նմուշների միջև բաժանումը (ընտրանքի հաճախականությունը) `կախված հետաքրքրության հաճախականությունից: Այս դեպքում, մենք օգտագործում ենք երկու նմուշների միջև հեռավորությունը, որն օգտագործվում է Hann պատուհանի գործառույթը կիրառելու, ինչպես նաև ամպլիտուդայի/RMS- ի հաշվարկի համար: Այս ծածկագիրը նույնպես կատարում է կոպիտ զրոյացում ՝ հանելով անալոգային ընթերցման արժեքից 500 -ը: Անհրաժեշտության դեպքում այս արժեքը կարող է փոխվել: Տիպիկ դեպքի համար այս արժեքները լավ են աշխատում: Ավելին, որոշ հետաձգումներ պետք է ավելացվեն `մոտ 1200 Հց նմուշառման հաճախականություն ունենալու համար: 1200 Հց նմուշառման հաճախականության դեպքում կարող է հայտնաբերվել առավելագույնը 600 Հց հաճախականություն:

համար (int i = 0; i <128; i ++) {a = analogRead (Mic_pin) -500; // կոպիտ զրոյական հերթափոխ sum1 = sum1+a; // միջին արժեքին sum2 = sum2+a*a; // դեպի RMS արժեքը a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // Hann պատուհան = 4*a; // float- ի համար int- ի փոխակերպման հետաձգում microseconds (195); // շահագործման հաճախականությունների տիրույթի հիման վրա}

2. FFT:

Տվյալների պատրաստ լինելուց հետո FFT- ն կատարվում է EasyFFT- ի միջոցով: Այս EasyFFT գործառույթը փոփոխված է ՝ 128 նմուշների համար FFT- ի ամրագրման համար: Կոդը փոփոխված է նաև հիշողության սպառումը նվազեցնելու համար: Բնօրինակ 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;} եթե (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. Յուրաքանչյուր հաճախության համար նոտա հաշվարկելուց հետո կարող է պատահել, որ գոյություն ունեն բազմաթիվ հաճախականություններ, որոնք հուշում են նույն նոտան: Outputշգրիտ ելքային կոդը ունենալու համար հաշվի են առնում նաև կրկնությունները: Կոդն ավելացնում է հաճախականության բոլոր արժեքները `ամպլիտուդայի կարգի և կրկնությունների հիման վրա և առավելագույն ամպլիտուդայով նշում է:

Քայլ 2: Դիմում

Կոդի օգտագործումը ուղիղ առաջ է, սակայն կան նաև բազմաթիվ սահմանափակումներ, որոնք պետք է հիշել դրա ընթացքում: Կոդը կարող է պատճենվել, քանի որ այն օգտագործվում է նշումների հայտնաբերման համար: Ստորև բերված կետերը պետք է հաշվի առնել այն օգտագործելիս:

1. Pin նշանակում.

Կցված Pin- ի հիման վրա առաջադրանքը պետք է փոփոխվի: Իմ փորձի համար ես այն պահեցի Անալոգային կապ 7 -ում, void setup () {Serial.begin (250000); Mic_pin = A7; }

2. Խոսափողի զգայունություն.

Խոսափողի զգայունությունը պետք է փոփոխվի, այնպես որ ալիքի ձևը կարող է առաջանալ լավ ամպլիտուդով: Հիմնականում խոսափողի մոդուլը գալիս է զգայունության կարգավորմամբ: համապատասխան զգայունություն ընտրելու այնպիսին, որ ազդանշանը ոչ շատ փոքր լինի, և ոչ էլ անջատվի ավելի մեծ ամպլիտուդի պատճառով:

3. Ամպլիտուդիայի շեմ.

Այս կոդը ակտիվանում է միայն այն դեպքում, երբ ազդանշանի ամպլիտուդը բավականաչափ բարձր է: այս կարգավորումը պետք է ձեռքով սահմանվի օգտագործողի կողմից: այս արժեքը կախված է խոսափողի զգայունությունից, ինչպես նաև կիրառությունից:

եթե (գումար 2-գումար 1> 5) {

..

վերը նշված ծածկագրում sum2- ը տալիս է RMS արժեք, մինչդեռ գումարը 1 տալիս է միջին արժեք: այնպես որ այս երկու արժեքների տարբերությունը տալիս է ձայնային ազդանշանի ամպլիտուդը: իմ դեպքում, այն ճիշտ է աշխատում `մոտ 5 -ի ամպլիտուդային արժեքով:

4. Լռելյայն, այս կոդը տպելու է հայտնաբերված նշումը: սակայն, եթե դուք պլանավորում եք օգտագործել նշումը այլ նպատակով, ապա պետք է օգտագործվի ուղղակիորեն տրված համարը: օրինակ C = 0; C#= 1, D = 2, D#= 3 և առաջ:

5. Եթե գործիքը ունի ավելի բարձր հաճախականություն, ծածկագիրը կարող է կեղծ ելք տալ: առավելագույն հաճախականությունը սահմանափակվում է նմուշառման հաճախականությամբ: այնպես որ կարող եք խաղալ հետաձգման ներքևի արժեքներով `օպտիմալ ելք ստանալու համար: ստորև նշված կոդի հետաձգմամբ ՝ 195 միկրո վայրկյան: որը կարող է շտկվել `օպտիմալ արդյունք ստանալու համար: Սա կազդի կատարման ընդհանուր տևողության վրա:

{a = analogRead (Mic_pin) -500; // կոպիտ զրոյական տեղաշարժ

գումար 1 = գումար 1+ա; // միջին արժեքին sum2 = sum2+a*a; // դեպի RMS արժեքը a = a*(sin (i*3.14/128)*sin (i*3.14/128)); // Hann պատուհան = 4*a; // float- ի համար int- ի փոխակերպման հետաձգում microseconds (195); // շահագործման հաճախականությունների տիրույթի հիման վրա}

6. այս կոդը կգործի միայն մինչև 2000 Հց հաճախականություն: վերացնելով նմուշառման միջև ուշացումը կարող է ձեռք բերել նմուշառման հաճախականությունների շուրջ 3-4 կՀց հաճախականությամբ:

Նախազգուշական միջոցներ:

  • Ինչպես նշվեց EasyFFT ձեռնարկում, FFT- ն ուտում է Arduino- ի հսկայական հիշողություն: Այսպիսով, եթե ունեք ծրագիր, որը պետք է պահի որոշ արժեքներ, խորհուրդ է տրվում օգտագործել ավելի բարձր հիշողություն ունեցող տախտակ:
  • Այս կոդը կարող է լավ աշխատել մի գործիքի/վոկալիստի համար, իսկ մյուսի համար ՝ վատ: Իրական ժամանակում ճշգրիտ հայտնաբերումը հնարավոր չէ հաշվողական սահմանափակումների պատճառով:

Քայլ 3: Ամառային

Նշումների հայտնաբերումը հաշվարկային ինտենսիվ աշխատանք է, իրական ժամանակում ելք ստանալը շատ դժվար է հատկապես Arduino- ում: Այս ծածկագիրը կարող է տալ մոտ 6,6 նմուշ /վայրկյան (195 միկրո վայրկյան ավելացված ուշացումով): այս կոդը լավ է աշխատում դաշնամուրի և որոշ այլ գործիքների հետ:

Հուսով եմ, որ այս ծածկագիրը և ձեռնարկը օգտակար կլինեն երաժշտության հետ կապված ձեր նախագծում: ցանկացած կասկածի կամ առաջարկության դեպքում ազատ զգացեք մեկնաբանել կամ ուղարկել հաղորդագրություն:

Առաջիկա ձեռնարկում ես կփոխեմ այս ծածկագիրը երաժշտական ակորդների հայտնաբերման համար: այնպես որ մնացեք լարված:

Խորհուրդ ենք տալիս: