Музыкалық нота детекторы: 3 қадам
Музыкалық нота детекторы: 3 қадам
Anonim
Image
Image

Аспапта ойналатын нотаны анықтайтын бұл жобамен достарыңыз бен туыстарыңызды таң қалдырыңыз. Бұл жоба электронды пернетақтада, фортепиано қосымшасында немесе кез келген басқа аспапта ойналатын музыкалық нотаны, сондай -ақ шамамен жиілікті көрсетеді.

Егжей

Бұл жоба үшін дыбыстық модуль детекторынан аналогтық шығу Arduino Uno аналогтық A0 кірісіне жіберіледі. Аналогтық сигнал іріктеледі және квантталады (цифрланған). Автокорреляция, салмақтау және баптау коды алғашқы 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 жылы жасалған
Түпнұсқа авторы: Клайд А. Летсом, PhD, PE, MEM
Сипаттама: Бұл код/эскизде электронды пернетақтада немесе фортепиано қосымшасында ойналатын музыкалық нотаны, сондай -ақ шамамен жиілікті көрсетеді. Бұл жоба үшін аналогтық шығыс
дыбыстық модуль детекторы Arduino Uno аналогтық A0 кірісіне жіберіледі. Аналогтық сигнал іріктеледі және квантталады (цифрланған). Автокорреляция, салмақтау және баптау коды қолданылады
алғашқы 3 периодты пайдалана отырып, негізгі жиілікті табыңыз. Шамамен фундаментальды жиілік 3, 4 және 5 октавалардағы жиіліктермен салыстырылып, ең жақын мюзиклді анықтайды.
жиілікті ескерту. Соңында ең жақын жиіліктің болжамды жазбасы экранға шығарылады.
Лицензия: Бұл бағдарлама ақысыз бағдарламалық қамтамасыз ету; сіз оны GNU General Public License (GPL) 3 нұсқасының шарттарына сәйкес немесе кез келген уақытта қайта таратуға және/немесе өзгертуге болады.
ақысыз бағдарламалық қамтамасыз ету қоры жариялаған сіздің нұсқаңыз.
Ескертулер: Copyright (c) 2020 авторы C. A. Lettsome Services, LLC
Қосымша ақпарат алу үшін https://clydelettsome.com/blog/2020/06/07/my-weekend-project-musical-note-detector-using-an-arduino/ сайтына кіріңіз.
*/
#үлгілерді 128 анықтаңыз // Arduino Uno үшін Max 128.
#анықтау SAMPLING_FREQUENCY 2048 // Fs = Nyquist негізінде, күтілетін жиіліктен 2 есе көп болуы керек.
#define OFFSETSAMPLES 40 // калибрлеу мақсатында қолданылады
#define TUNER -3 // C3 130.50 болғанша реттеңіз
өзгермелі іріктеу кезеңі;
қол қойылмаған ұзақ микросекундтар;
int X [ҮЛГІЛЕР]; // нақты мәндерді ұстау үшін SAMPLES өлшемінің векторын жасаңыз
float autoCorr [SAMPLES]; // қиялдық мәндерді ұстау үшін SAMPLES өлшемді векторын жасаңыз
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]; // офсеттік векторды құру
int avgOffSet; // офсеттік векторды құру
int i, k, periodEnd, periodBegin, кезең, реттегіш, noteLocation, octaveRange;
float maxValue, minValue;
ұзақ сома;
int thresh = 0;
int numOfCycles = 0;
өзгермелі сигналЖиілік, сигналЖиілік2, сигналЖиілік3, сигналЖиілікҚабыл, жалпы;
байт күйі_машина = 0;
int samplePerPeriod = 0;
жарамсыз орнату ()
{
Serial.begin (115200); // 115200 Сериялық монитор үшін бер жылдамдығы
}
бос цикл ()
{
//*****************************************************************
// Калабрация бөлімі
//*****************************************************************
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 секундқа кідірту
//*****************************************************************
// A0 үлгісінен SAMPLES үлгілерін жинау, іріктеу кезеңінің іріктеу кезеңі
//*****************************************************************
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Период микросекундтарда
үшін (i = 0; i <ҮЛГІЛЕР; i ++)
{
microSeconds = micros (); // Arduino тақтасы ағымдағы сценарийді іске қосқаннан бері микросекундтар санын қайтарады.
X = analogRead (0); // 0 (A0) аналогтық түйреуіштен мәнді оқиды, оны сандық түрде анықтайды және оны нақты термин ретінде сақтайды.
/ *қажет болған жағдайда бірнеше секунд ішінде үлгілер арасындағы күту уақыты қалады */
while (micros () <(microSeconds + (samplePeriod * 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 == 0 && i == 0)
{
thres = 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)
{
periodBegin = i-1;
күй_машина = 2;
numOfCycles = 1;
samplePerPeriod = (periodBegin - 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, 1 және 2 цикл үшін 2 периодты табыңыз
{
maxValue = autoCorr ;
}
әйтпесе (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
күй_машина = 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, 1, 2 және 3 цикл үшін 3 периодты табыңыз
{
maxValue = autoCorr ;
}
әйтпесе (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
күй_машина = 4;
numOfCycles = 3;
samplePerPeriod = (periodEnd - 0);
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-реттегіш; // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// Нәтижені талдау
//*****************************************************************
егер (samplePerPeriod == 0)
{
Serial.println («Хмм ….. мен сенімді емеспін. Сіз мені алдағыңыз келе ме?»);
}
басқа
{
// салмақтау функциясын дайындау
жалпы = 0;
if (signalFrequency! = 0)
{
барлығы = 1;
}
егер (signalFrequency2! = 0)
{
жалпы = барлығы + 2;
}
егер (signalFrequency3! = 0)
{
жалпы = барлығы + 3;
}
// салмақтау функциясын қолдана отырып жиілікті есептеңіз
signalFrequencyGuess = ((1/total) * signalFrequency) + ((2/total) * signalFrequency2) + ((3/total) * signalFrequency3); // өлшенген жиілікті табыңыз
Serial.print («Сіз ойнаған нота шамамен»);
Serial.print (signalFrequencyGuess); // Жиілікті болжауды басып шығарыңыз.
Serial.println («Гц.»);
// болжам негізінде октавалық диапазонды табыңыз
octaveRange = 3;
while (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7))
{
үшін (i = 0; i <12; i ++)
{
storageNoteFreq = 2 * storageNoteFreq ;
}
octaveRange ++;
}
// Ең жақын жазбаны табыңыз
minValue = 10000000;
noteLocation = 0;
үшін (i = 0; i <12; i ++)
{
if (minValue> abs (signalFrequencyGuess-storedNoteFreq )))
{
minValue = abs (signalFrequencyGuess-storedNoteFreq );
noteLocation = i;
}
}
// Жазбаны басып шығарыңыз
Serial.print («Менің ойымша, сен ойнадың»);
егер (noteLocation == 0)
{
Serial.print («C»);
}
әйтпесе (noteLocation == 1)
{
Serial.print («C#»);
}
әйтпесе (noteLocation == 2)
{
Serial.print («D»);
}
әйтпесе (noteLocation == 3)
{
Serial.print («D#»);
}
әйтпесе (noteLocation == 4)
{
Serial.print («E»);
}
егер басқа болса (noteLocation == 5)
{
Serial.print («F»);
}
әйтпесе (noteLocation == 6)
{
Serial.print («F#»);
}
егер басқа болса (noteLocation == 7)
{
Serial.print («G»);
}
әйтпесе (noteLocation == 8)
{
Serial.print («G#»);
}
егер басқа болса (noteLocation == 9)
{
Serial.print («A»);
}
әйтпесе (noteLocation == 10)
{
Serial.print («A#»);
}
әйтпесе (noteLocation == 11)
{
Serial.print («B»);
}
Serial.println (octaveRange);
}
//*****************************************************************
//Осы жерде тоқтаңыз. Қайта іске қосу үшін Arduino -ны қалпына келтіру түймесін басыңыз
//*****************************************************************
кезінде (1);
}

GitHub ❤ арқылы орналастырылған rawgistfile1.txt файлын қарау

3 -қадам: Музыкалық ноталар детекторын орнатыңыз

Arduino Uno бағдарламасын компьютерге Arduino IDE -де жазылған немесе жүктелген кодпен қосыңыз. Кодты құрастырыңыз және Arduino -ға жүктеңіз. Схеманы музыка көзіне жақын қойыңыз. Ескерту: Кіріспе бейнеде мен музыка көзі ретінде планшетке компьютерді динамиктермен бірге орнатылған қосымшаны қолданамын. Arduino тақтасындағы қалпына келтіру түймесін басыңыз, содан кейін музыка көзінде жазбаны ойнатыңыз. Бірнеше секундтан кейін музыкалық нота детекторы ойнатылған нотаны және оның жиілігін көрсетеді.

Ұсынылған: