Съдържание:
- Консумативи
- Стъпка 1: Конструирайте хардуера за детектора на музикални ноти
- Стъпка 2: Програмирайте детектора за музикални ноти
- Стъпка 3: Настройте детектора за музикални ноти
Видео: Детектор на музикални ноти: 3 стъпки
2024 Автор: John Day | [email protected]. Последно модифициран: 2024-01-30 07:50
Удивете приятелите и семейството си с този проект, който открива нотата, свирена от инструмент. Този проект ще показва приблизителната честота, както и музикалната нота, свирена на електронна клавиатура, приложение за пиано или друг инструмент.
Подробности
За този проект аналоговият изход от детектора на звуков модул се изпраща към аналоговия вход 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: Програмирайте детектора за музикални ноти
В IDE на Arduino добавете следния код.
gistfile1.txt
/* |
Име на файл/скица: MusicalNoteDetector |
Версия №: v1.0 Създадено на 7 юни 2020 г. |
Оригинален автор: Clyde A. Lettsome, PhD, PE, MEM |
Описание: Този код/скица показва приблизителната честота, както и музикалната нота, свирена на електронна клавиатура или приложение за пиано. За този проект аналоговият изход от |
детектор на звуков модул се изпраща към аналоговия вход A0 на Arduino Uno. Аналоговият сигнал се избира и квантува (дигитализира). Кодът за автокорелация, претегляне и настройка е използван за |
намерете основна честота, като използвате първите 3 периода. Приблизителната основна честота се сравнява с честотите в октави 3, 4 и 5, за да се определи най -близкият мюзикъл |
бележка честота. Накрая познатата бележка за най -близката честота се отпечатва на екрана. |
Лиценз: Тази програма е безплатен софтуер; можете да го разпространявате и/или да го променяте съгласно условията на GNU General Public License (GPL) версия 3 или по -късно |
версия по ваш избор, публикувана от Фондацията за свободен софтуер. |
Бележки: Авторско право (c) 2020 от C. A. Lettsome Services, LLC |
За повече информация посетете |
*/ |
#define SAMPLES 128 // Max 128 за Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 // Fs = Въз основа на Nyquist, трябва да бъде 2 пъти най -високата очаквана честота. |
#define OFFSETSAMPLES 40 // използвани за калабриране |
#define TUNER -3 // Регулирайте, докато C3 е 130.50 |
период на вземане на проби от флоат; |
неподписани дълги микросекунди; |
int X [ПРИБРИ]; // създаване на вектор с размер SAMPLES за съхранение на реални стойности |
float autoCorr [ПРИМЕРИ]; // създаване на вектор с размер 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, октаваRange; |
float maxValue, minValue; |
дълга сума; |
int thresh = 0; |
int numOfCycles = 0; |
плаващ сигналFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, общо; |
байт state_machine = 0; |
int samplePerPeriod = 0; |
void setup () |
{ |
Serial.begin (115200); // 115200 Скорост на предаване за сериен монитор |
} |
void loop () |
{ |
//***************************************************************** |
// Раздел за калибриране |
//***************************************************************** |
Serial.println ("Калабриране. Моля, не пускайте никакви ноти по време на калибриране."); |
за (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 с период на извадка от период на вземане на проби |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Период в микросекунди |
за (i = 0; i <ПРИБОРИ; i ++) |
{ |
microSeconds = micros (); // Връща броя микросекунди, откакто дъската на Arduino започна да изпълнява текущия скрипт. |
X = analogRead (0); // Чете стойността от аналогов извод 0 (A0), квантува я и я записва като реален термин. |
/ *оставащо време на изчакване между пробите, ако е необходимо, в секунди */ |
while (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 = сума / ПРОБИ; |
// Първа машина за откриване на върхови състояния |
if (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) |
{ |
periodBegin = i-1; |
състояние_машина = 2; |
numOfCycles = 1; |
samplePerPeriod = (periodBegin - 0); |
период = пробиPerPeriod; |
регулатор = 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) |
{ |
periodEnd = i-1; |
състояние_машина = 3; |
numOfCycles = 2; |
samplePerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-регулатор; // f = (2*fs)/(2*N) |
maxValue = 0; |
} |
else if (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) |
{ |
periodEnd = i-1; |
състояние_машина = 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 ("Hz."); |
// намиране на октавен диапазон въз основа на предположението |
octaveRange = 3; |
while (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7)) |
{ |
за (i = 0; i <12; i ++) |
{ |
storedNoteFreq = 2 * storedNoteFreq ; |
} |
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); |
} |
вижте rawgistfile1.txt, хостван с ❤ от GitHub
Стъпка 3: Настройте детектора за музикални ноти
Свържете Arduino Uno към компютъра с кода, написан или зареден в Arduino IDE. Компилирайте и качете кода в Arduino. Поставете веригата близо до източника на музика. Забележка: Във видеото за въвеждане използвам приложение, инсталирано на таблет, заедно с високоговорителите на компютъра, като източник на музика. Натиснете бутона за нулиране на дъската на Arduino и след това пуснете бележка от източника на музика. След няколко секунди детекторът за музикални ноти ще покаже изсвирената нота и нейната честота.
Препоръчано:
Направи си сам музикални коледни светлини (MSGEQ7 + Arduino): 6 стъпки (със снимки)
Направи си сам музикални коледни светлини (MSGEQ7 + Arduino): Така че всяка година казвам, че ще направя това и никога няма да го направя, защото отлагам много. 2020 е година на промяна, затова казвам, че това е годината за това. Така че се надявам да ви хареса и да направите свои собствени музикални коледни светлини. Това ще бъде s
Музикални кегли: 4 стъпки
Музикални кегли: Едно нещо като баба и дядо е, че винаги търсите нови и вълнуващи начини да забавлявате прекрасните си внуци; и по такъв начин, който също ви позволява да се занимавате със собствените си хобита. Въведете музикалния кегъл. Използване на ATTiny13 (б
Детектор за музикални бележки на Arduino: 3 стъпки
Детектор за музикални бележки на Arduino: Откриването на музикални ноти от аудио сигнала е трудно да се направи, особено на Arduino, поради ограничената памет и мощност на обработка. Като цяло бележката не е чиста синусоида, която затруднява откриването. Ако вземем честотната трансформация на va
Как да кодирате песен, използвайки ноти в Sonic Pi: 5 стъпки
Как да кодирате песен, използвайки ноти в Sonic Pi: Тази инструкция ще очертае някои основни стъпки и парчета код, които да използвате, когато кодирате песен в Sonic Pi, използвайки ноти! Има милион други парчета код, които да опитате да добавите аромат към готовото си парче, така че не забравяйте също да играете наоколо
IOT детектор за дим: Актуализирайте съществуващ детектор за дим с IOT: 6 стъпки (със снимки)
IOT Smote Detector: Актуализирайте съществуващия детектор на дим с IOT: Списък на сътрудниците, Изобретател: Tan Siew Chin, Tan Yit Peng, Tan Wee Heng Надзорник: Д -р Chia Kim Seng Катедра по мехатронно и роботизирано инженерство, Факултет по електротехника и електронно инженерство, Universiti Tun Хюсеин Он Малайзия. Разпространение