Оглавление:
- Запасы
- Шаг 1. Создайте оборудование для детектора музыкальных нот
- Шаг 2: запрограммируйте детектор музыкальных нот
- Шаг 3: Настройте Детектор музыкальных нот
Видео: Детектор музыкальных нот: 3 шага
2024 Автор: John Day | [email protected]. Последнее изменение: 2024-01-30 11:48
Удивите своих друзей и семью этим проектом, который распознает ноты, сыгранные на инструменте. В этом проекте будет отображаться приблизительная частота, а также музыкальная нота, сыгранная на электронной клавиатуре, приложении для фортепиано или любом другом инструменте.
Подробности
В этом проекте аналоговый выход детектора звукового модуля отправляется на аналоговый вход A0 Arduino Uno. Аналоговый сигнал дискретизируется и квантуется (оцифровывается). Код автокорреляции, взвешивания и настройки используется для нахождения основной частоты с использованием первых 3 периодов. Затем приблизительная основная частота сравнивается с частотами в диапазоне октав 3, 4 и 5 для определения ближайшей частоты музыкальной ноты. Наконец, на экране печатается предполагаемое примечание для ближайшей частоты.
Примечание. В этом руководстве рассказывается только о том, как построить проект. Для получения дополнительной информации о деталях и обоснованиях дизайна перейдите по этой ссылке: Подробнее
Запасы
- (1) Arduino Uno (или Genuino Uno)
- (1) Совместимость с модулем обнаружения звука высокой чувствительности датчика микрофона DEVMO
- (1) Макетная плата без пайки
- (1) Кабель USB-A - B
- Провода перемычки
- Музыкальный источник (фортепиано, клавиатура или приложение paino с динамиками)
- (1) Компьютер или ноутбук
Шаг 1. Создайте оборудование для детектора музыкальных нот
Используя Arduino Uno, соединительные провода, макетную плату без пайки и модуль обнаружения звука высокой чувствительности датчика микрофона DEVMO (или аналогичный), создайте схему, показанную на этом изображении.
Шаг 2: запрограммируйте детектор музыкальных нот
В IDE Arduino добавьте следующий код.
gistfile1.txt
/* |
Имя файла / эскиза: MusicalNoteDetector |
Номер версии: v1.0 Создано 7 июня 2020 г. |
Автор оригинала: Клайд А. Леттсом, PhD, PE, MEM |
Описание: этот код / эскиз отображает приблизительную частоту, а также музыкальную ноту, сыгранную на электронной клавиатуре или в приложении для фортепиано. Для этого проекта аналоговый выход из |
Звуковой модуль детектора отправляется на аналоговый вход A0 Arduino Uno. Аналоговый сигнал дискретизируется и квантуется (оцифровывается). Код автокорреляции, взвешивания и настройки используется для |
найти основную частоту, используя первые 3 периода. Затем приблизительная основная частота сравнивается с частотами в диапазоне 3, 4 и 5 октав для определения ближайшего музыкального |
обратите внимание на частоту. Наконец, на экране печатается предполагаемое примечание для ближайшей частоты. |
Лицензия: Эта программа является бесплатным программным обеспечением; вы можете распространять и / или изменять его в соответствии с условиями Стандартной общественной лицензии GNU (GPL) версии 3 или любой более поздней. |
версия по вашему выбору, опубликованная Free Software Foundation. |
Примечания: Copyright (c) 2020 by C. A. Lettsome Services, LLC |
Для получения дополнительной информации посетите |
*/ |
#define SAMPLES 128 // Макс 128 для Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 // Fs = на основе Найквиста, должно быть в 2 раза больше максимальной ожидаемой частоты. |
#define OFFSETSAMPLES 40 // используется для калибровки |
#define TUNER -3 // Регулируйте, пока C3 не станет 130,50 |
float samplingPeriod; |
беззнаковые длинные микросекунды; |
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 [СМЕЩЕНИЯ]; // создаем вектор смещения |
int avgOffSet; // создаем вектор смещения |
int i, k, periodEnd, periodBegin, period, adjuster, noteLocation, octaveRange; |
float maxValue, minValue; |
длинная сумма; |
int thresh = 0; |
int numOfCycles = 0; |
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total; |
байт state_machine = 0; |
int samplesPerPeriod = 0; |
установка void () |
{ |
Serial.begin (115200); // 115200 бод для последовательного монитора |
} |
пустой цикл () |
{ |
//***************************************************************** |
// Раздел калибровки |
//***************************************************************** |
Serial.println («Калибровка. Пожалуйста, не играйте никаких нот во время калибровки.»); |
for (i = 0; i <OFFSETSAMPLES; i ++) |
{ |
offSet = analogRead (0); // Считывает значение с аналогового вывода 0 (A0), квантует его и сохраняет как действительный член. |
//Serial.println(offSet); // используйте это, чтобы настроить модуль обнаружения звука примерно на половину или 512, когда звук не воспроизводится. |
sumOffSet = sumOffSet + offSet [я]; |
} |
samplesPerPeriod = 0; |
maxValue = 0; |
//***************************************************************** |
// Готовимся принять ввод от A0 |
//***************************************************************** |
avgOffSet = round (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 <ОБРАЗЦЫ; i ++) |
{ |
микросекунды = микросекунды (); // Возвращает количество микросекунд, прошедших с того момента, как плата Arduino начала запускать текущий скрипт. |
X = analogRead (0); // Считывает значение с аналогового вывода 0 (A0), квантует его и сохраняет как действительный член. |
/ * оставшееся время ожидания между выборками, если необходимо, в секундах * / |
а (микросекунды () <(микросекунды + (период выборки * 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 = сумма / ОБРАЗЦЫ; |
// Конечный автомат первого обнаружения пика |
если (state_machine == 0 && i == 0) |
{ |
порог = autoCorr * 0,5; |
state_machine = 1; |
} |
else if (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, найти 1 период для использования первого цикла |
{ |
maxValue = autoCorr ; |
} |
иначе 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; |
samplesPerPeriod = (periodBegin - 0); |
период = samplesPerPeriod; |
регулятор = TUNER + (50.04 * exp (-0.102 * samplesPerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod)) - регулятор; // f = fs / N |
} |
else if (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, найти 2 периода для 1-го и 2-го цикла |
{ |
maxValue = autoCorr ; |
} |
иначе 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; |
samplesPerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - регулятор; // 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 ; |
} |
иначе 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; |
samplesPerPeriod = (periodEnd - 0); |
signalFrequency3 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - регулятор; // f = (3 * fs) / (3 * N) |
} |
} |
//***************************************************************** |
// Анализ результатов |
//***************************************************************** |
если (samplesPerPeriod == 0) |
{ |
Serial.println («Хм….. я не уверен. Вы пытаетесь меня обмануть?»); |
} |
еще |
{ |
// подготавливаем весовую функцию |
всего = 0; |
если (частота сигнала! = 0) |
{ |
всего = 1; |
} |
если (signalFrequency2! = 0) |
{ |
итого = всего + 2; |
} |
если (signalFrequency3! = 0) |
{ |
итого = всего + 3; |
} |
// вычисляем частоту с помощью весовой функции |
signalFrequencyGuess = ((1 / всего) * 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)) |
{ |
для (я = 0; я <12; я ++) |
{ |
storedNoteFreq = 2 * storedNoteFreq ; |
} |
octaveRange ++; |
} |
// Находим ближайшую заметку |
minValue = 10000000; |
noteLocation = 0; |
для (я = 0; я <12; я ++) |
{ |
если (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 («А»); |
} |
иначе, если (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, а затем сыграйте ноту на источнике музыки. Через несколько секунд детектор музыкальных нот отобразит сыгранную ноту и ее частоту.
Рекомендуемые:
Детектор музыкальных нот Arduino: 3 шага
Детектор музыкальных нот Arduino: обнаружение музыкальных нот по аудиосигналу затруднено, особенно на Arduino, из-за ограниченной памяти и вычислительной мощности. Как правило, нота не является чистой синусоидой, что затрудняет обнаружение. Если мы возьмем частотное преобразование va
Колесо музыкальных впечатлений сегодняшнего шоу: 7 шагов
Колесо музыкальных впечатлений сегодняшнего шоу. Эта машина вдохновлена фрагментом вечернего шоу, в котором Джимми Фэллон в главной роли называется «Колесо музыкальных впечатлений». Сначала вы нажимаете кнопку на коробке, и на ЖК-дисплее отображается случайный певец и песня. Тогда вам придется подражать
4 схемы музыкальных реактивных светодиодов -- Кабель MIC / AUX / динамик: 3 шага
4 схемы музыкальных реактивных светодиодов || Кабель MIC / AUX / динамик: это схема, которая реагирует на окружающую музыку и светит светодиодами в такт музыке. Здесь я покажу вам четыре различных способа создания схемы музыкальных реактивных светодиодов, используя: -1. Одиночный транзистор 2. Два транзистора 3. Кабель AUX 4. Оратор
Как закодировать песню с использованием нот в Sonic Pi: 5 шагов
Как кодировать песню с использованием нот в Sonic Pi: в этом руководстве будут описаны некоторые основные шаги и фрагменты кода, которые необходимо использовать при кодировании песни в Sonic Pi с использованием нот! Есть миллион других фрагментов кода, чтобы попытаться добавить изюминку к вашей готовой части, так что не забудьте также поиграть с y
Портативная музыкальная шкатулка / инструмент на 6 нот (легко сделать и улучшить!): 5 шагов (с изображениями)
Портативная музыкальная шкатулка / инструмент на 6 нот (легко сделать и улучшить!) Привет! Вдохновленный Мартином Молином, участником шведской группы Wintergatan, я недавно влюбился в музыкальные шкатулки и все, что с ними связано. Люди, пишущие песни для музыкальных шкатулок, все еще используют старомодный способ пробивать песню, а не