Tabla de contenido:
- Suministros
- Paso 1: construya el hardware para el detector de notas musicales
- Paso 2: programe el detector de notas musicales
- Paso 3: configura el detector de notas musicales
Video: Detector de notas musicales: 3 pasos
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:40
Sorprenda a sus amigos y familiares con este proyecto que detecta la nota tocada por un instrumento. Este proyecto mostrará la frecuencia aproximada, así como la nota musical tocada en un teclado electrónico, aplicación de piano o cualquier otro instrumento.
Detalles
Para este proyecto, la salida analógica del detector del módulo de sonido se envía a la entrada analógica A0 del Arduino Uno. La señal analógica se muestrea y cuantifica (digitaliza). El código de autocorrelación, ponderación y sintonía se utiliza para encontrar la frecuencia fundamental utilizando los primeros 3 períodos. Luego, la frecuencia fundamental aproximada se compara con las frecuencias en el rango de octavas 3, 4 y 5 para determinar la frecuencia de nota musical más cercana. Finalmente, la nota adivinada para la frecuencia más cercana se imprime en la pantalla.
Nota: Este instructivo solo se enfoca en cómo construir el proyecto. Para obtener más información sobre los detalles y las justificaciones del diseño, visite este enlace: Más información
Suministros
- (1) Arduino Uno (o Genuino Uno)
- (1) Módulo de detección de sonido de alta sensibilidad con sensor de micrófono DEVMO Compatible
- (1) Placa de pruebas sin soldadura
- (1) Cable USB-A a B
- Cables de puente
- Fuente musical (piano, teclado o aplicación paino con altavoces)
- (1) Computadora o laptop
Paso 1: construya el hardware para el detector de notas musicales
Usando un Arduino Uno, cables de conexión, una placa de prueba sin soldadura y un Módulo de detección de sonido de alta sensibilidad con sensor de micrófono DEVMO (o similar) construya el circuito que se muestra en esta imagen
Paso 2: programe el detector de notas musicales
En el IDE de Arduino, agregue el siguiente código.
gistfile1.txt
/* |
Nombre de archivo / boceto: MusicalNoteDetector |
Número de versión: v1.0 Creado el 7 de junio de 2020 |
Autor original: Clyde A. Lettsome, PhD, PE, MEM |
Descripción: este código / boceto muestra la frecuencia aproximada, así como la nota musical tocada en un teclado electrónico o aplicación de piano. Para este proyecto, la salida analógica del |
El detector de módulo de sonido se envía a la entrada analógica A0 del Arduino Uno. La señal analógica se muestrea y cuantifica (digitaliza). El código de autocorrelación, ponderación y ajuste se utiliza para |
encuentre la frecuencia fundamental utilizando los primeros 3 períodos. Luego, la frecuencia fundamental aproximada se compara con las frecuencias en el rango de octavas 3, 4 y 5 para determinar la frecuencia musical más cercana. |
nota la frecuencia. Finalmente, la nota adivinada para la frecuencia más cercana se imprime en la pantalla. |
Licencia: este programa es software gratuito; puede redistribuirlo y / o modificarlo bajo los términos de la Licencia Pública General GNU (GPL) versión 3, o cualquier posterior |
versión de su elección, según lo publicado por la Free Software Foundation. |
Notas: Copyright (c) 2020 de C. A. Lettsome Services, LLC |
Para obtener más información, visite |
*/ |
#define SAMPLES 128 // Max 128 para Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 // Fs = Basado en Nyquist, debe ser 2 veces la frecuencia más alta esperada. |
#define OFFSETSAMPLES 40 // utilizado con fines de calabrating |
#define TUNER -3 // Ajustar hasta que C3 sea 130.50 |
período de muestreo flotante; |
microSegundos largos sin firmar; |
int X [MUESTRAS]; // crea un vector de tamaño MUESTRAS para contener valores reales |
flotar autoCorr [MUESTRAS]; // crea un vector de tamaño MUESTRAS para contener valores imaginarios |
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]; // crear vector de compensación |
int avgOffSet; // crear vector de compensación |
int i, k, periodEnd, periodBegin, period, ajustador, noteLocation, octaveRange; |
float maxValue, minValue; |
suma larga |
int thresh = 0; |
int numOfCycles = 0; |
flotar signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total; |
byte state_machine = 0; |
int samplesPerPeriod = 0; |
configuración vacía () |
{ |
Serial.begin (115200); // 115200 Velocidad en baudios para el monitor en serie |
} |
bucle vacío () |
{ |
//***************************************************************** |
// Sección de Calabration |
//***************************************************************** |
Serial.println ("Calabrating. Por favor, no toque ninguna nota durante la calabration."); |
para (i = 0; i <MUESTRAS DESPLAZADAS; i ++) |
{ |
offSet = analogRead (0); // Lee el valor del pin analógico 0 (A0), lo cuantifica y lo guarda como término real. |
//Serial.println(offSet); // use esto para ajustar el módulo de detección de sonido a aproximadamente la mitad o 512 cuando no se reproduce ningún sonido. |
sumOffSet = sumOffSet + offSet ; |
} |
samplesPerPeriod = 0; |
maxValue = 0; |
//***************************************************************** |
// Prepárese para aceptar la entrada de A0 |
//***************************************************************** |
avgOffSet = round (sumOffSet / OFFSETSAMPLES); |
Serial.println ("Cuenta regresiva"); |
retraso (1000); // pausa por 1 segundo |
Serial.println ("3"); |
retraso (1000); // pausa por 1 segundo |
Serial.println ("2"); |
retraso (1000); // pausa por 1 |
Serial.println ("1"); |
retraso (1000); // pausa por 1 segundo |
Serial.println ("¡Toca tu nota!"); |
retraso (250); // pausa durante 1/4 de segundo para el tiempo de reacción |
//***************************************************************** |
// Recolectar MUESTRAS muestras de A0 con período de muestreo de período de muestreo |
//***************************************************************** |
SamplePeriod = 1.0 / SAMPLING_FREQUENCY; // Periodo en microsegundos |
para (i = 0; i <MUESTRAS; i ++) |
{ |
microSegundos = micros (); // Devuelve el número de microsegundos desde que la placa Arduino comenzó a ejecutar el script actual. |
X = analogRead (0); // Lee el valor del pin analógico 0 (A0), lo cuantifica y lo guarda como término real. |
/ * tiempo de espera restante entre muestras si es necesario en segundos * / |
while (micros () <(microsegundos + (período de muestreo * 1000000))) |
{ |
// no hagas nada solo espera |
} |
} |
//***************************************************************** |
// Función de autocorrelación |
//***************************************************************** |
para (i = 0; i <MUESTRAS; i ++) // i = retraso |
{ |
suma = 0; |
for (k = 0; k <SAMPLES - i; k ++) // Emparejar señal con señal retardada |
{ |
suma = suma + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] es la señal y X [k + i] es la versión retrasada |
} |
autoCorr = suma / MUESTRAS; |
// Primera máquina de estado de detección de picos |
si (state_machine == 0 && i == 0) |
{ |
umbral = autoCorr * 0,5; |
state_machine = 1; |
} |
else if (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, encuentra 1 período para usar el primer ciclo |
{ |
maxValue = autoCorr ; |
} |
else 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); |
period = samplesPerPeriod; |
ajustador = TUNER + (50.04 * exp (-0.102 * samplesPerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod)) - ajustador; // f = fs / N |
} |
else if (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, encuentra 2 períodos para el 1er y 2do ciclo |
{ |
maxValue = autoCorr ; |
} |
else 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)) - ajustador; // f = (2 * fs) / (2 * N) |
maxValue = 0; |
} |
else if (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, encuentre 3 períodos para el 1er, 2do y 3er ciclo |
{ |
maxValue = autoCorr ; |
} |
else 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)) - ajustador; // f = (3 * fs) / (3 * N) |
} |
} |
//***************************************************************** |
//Análisis de resultados |
//***************************************************************** |
si (samplesPerPeriod == 0) |
{ |
Serial.println ("Hmm….. No estoy seguro. ¿Estás tratando de engañarme?"); |
} |
demás |
{ |
// preparar la función de ponderación |
total = 0; |
si (señalFrecuencia! = 0) |
{ |
total = 1; |
} |
si (señalFrecuencia2! = 0) |
{ |
total = total + 2; |
} |
si (señalFrecuencia3! = 0) |
{ |
total = total + 3; |
} |
// calcula la frecuencia usando la función de ponderación |
señalFrecuenciaGuess = ((1 / total) * señalFrecuencia) + ((2 / total) * señalFrecuencia2) + ((3 / total) * señalFrecuencia3); // encontrar una frecuencia ponderada |
Serial.print ("La nota que tocó es aproximadamente"); |
Serial.print (signalFrequencyGuess); // Imprime la estimación de frecuencia. |
Serial.println ("Hz."); |
// encuentra el rango de octava basado en la suposición |
octaveRange = 3; |
while (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7)) |
{ |
para (i = 0; i <12; i ++) |
{ |
storedNoteFreq = 2 * storedNoteFreq ; |
} |
octaveRange ++; |
} |
// Encuentra la nota más cercana |
minValue = 10000000; |
noteLocation = 0; |
para (i = 0; i <12; i ++) |
{ |
if (minValue> abs (signalFrequencyGuess-storedNoteFreq )) |
{ |
minValue = abs (signalFrequencyGuess-storedNoteFreq ); |
noteLocation = i; |
} |
} |
// Imprime la nota |
Serial.print ("Creo que jugaste"); |
si (noteLocation == 0) |
{ |
Serial.print ("C"); |
} |
else if (noteLocation == 1) |
{ |
Serial.print ("C #"); |
} |
más si (noteLocation == 2) |
{ |
Serial.print ("D"); |
} |
más si (noteLocation == 3) |
{ |
Serial.print ("D #"); |
} |
más si (noteLocation == 4) |
{ |
Serial.print ("E"); |
} |
más si (noteLocation == 5) |
{ |
Serial.print ("F"); |
} |
más si (noteLocation == 6) |
{ |
Serial.print ("F #"); |
} |
más si (noteLocation == 7) |
{ |
Serial.print ("G"); |
} |
más si (noteLocation == 8) |
{ |
Serial.print ("G #"); |
} |
más si (noteLocation == 9) |
{ |
Serial.print ("A"); |
} |
más si (noteLocation == 10) |
{ |
Serial.print ("A #"); |
} |
más si (noteLocation == 11) |
{ |
Serial.print ("B"); |
} |
Serial.println (octaveRange); |
} |
//***************************************************************** |
//Deténgase aquí. Presione el botón de reinicio en Arduino para reiniciar |
//***************************************************************** |
mientras (1); |
} |
ver rawgistfile1.txt alojado con ❤ por GitHub
Paso 3: configura el detector de notas musicales
Conecte el Arduino Uno a la PC con el código escrito o cargado en el IDE de Arduino. Compile y cargue el código en Arduino. Coloque el circuito cerca de la fuente de música. Nota: En el video de introducción, utilizo una aplicación instalada en la tableta junto con los parlantes de la PC como fuente de música. Presione el botón de reinicio en la placa Arduino y luego toque una nota en la fuente de música. Después de unos segundos, el detector de notas musicales mostrará la nota tocada y su frecuencia.
Recomendado:
Amplificador impreso en 3D para instrumentos musicales eléctricos: 11 pasos (con imágenes)
Un amplificador impreso en 3D para instrumentos musicales eléctricos .: Definición del proyecto. Espero hacer un amplificador imprimible para usar con un violín eléctrico o cualquier otro instrumento eléctrico. amplificador activo y manténgalo pequeño
Luces navideñas musicales automáticas de bricolaje (MSGEQ7 + Arduino): 6 pasos (con imágenes)
Luces navideñas musicales automáticas de bricolaje (MSGEQ7 + Arduino): Entonces, todos los años digo que voy a hacer esto y nunca lo haré porque procrastino mucho. 2020 es un año de cambios, así que digo que este es el año para hacerlo. Así que espero que les guste y hagan sus propias luces navideñas musicales. Esto va a ser una s
Skittles musicales: 4 pasos
Musical Skittles: Una cosa acerca de ser abuelo es que siempre estás buscando nuevas y emocionantes formas de entretener a tus maravillosos nietos; y de tal forma que además te permita jugar en tus propias aficiones. Entra en el bolo musical. Usando un ATTiny13 (b
Zapatos MIDI musicales: 5 pasos (con imágenes)
Zapatos MIDI musicales: como muchas personas, a menudo me encuentro inconscientemente dando golpecitos con los pies, ya sea con una canción o por algún hábito nervioso. Sin embargo, por divertido que sea, siempre sentí que me faltaba algo. Si tan solo pudiera activar los sonidos de decir, un
Detector de notas musicales Arduino: 3 pasos
Detector de notas musicales de Arduino: la detección de notas musicales a partir de la señal de audio es difícil de hacer, especialmente en Arduino debido a la memoria limitada y la potencia de procesamiento. Generalmente, la nota no es una onda sinusoidal pura que dificulta la detección. Si tomamos la transformada de frecuencia de va