Taula de continguts:
- Subministraments
- Pas 1: construïu el maquinari per al detector de notes musicals
- Pas 2: programa el Detector de notes musicals
- Pas 3: configureu el detector de notes musicals
Vídeo: Detector de notes musicals: 3 passos
2024 Autora: John Day | [email protected]. Última modificació: 2024-01-30 08:11
Sorprèn als teus amics i familiars amb aquest projecte que detecta la nota que toca un instrument. Aquest projecte mostrarà la freqüència aproximada, així com la nota musical reproduïda en un teclat electrònic, una aplicació de piano o qualsevol altre instrument.
Detalls
Per a aquest projecte, la sortida analògica del detector del mòdul de so s’envia a l’entrada analògica A0 de l’Arduino Uno. El senyal analògic es mostra i es quantifica (digitalitza). El codi d’autocorrelació, ponderació i afinació s’utilitza per trobar la freqüència fonamental mitjançant els primers 3 períodes. A continuació, es compara la freqüència fonamental aproximada amb les freqüències del rang de les octaves 3, 4 i 5 per determinar la freqüència de notes musicals més propera. Finalment, la nota endevinada de la freqüència més propera s’imprimeix a la pantalla.
Nota: aquesta instrucció només es centra en com construir el projecte. Per obtenir més informació sobre els detalls i les justificacions de disseny, visiteu aquest enllaç: Més informació
Subministraments
- (1) Arduino Uno (o Genuino Uno)
- (1) Compatible amb mòdul de detecció de so d'alta sensibilitat del sensor de micròfon DEVMO
- (1) Taula de pa sense soldadura
- (1) Cable USB-A a B.
- Filferros de pont
- Font musical (piano, teclat o aplicació paino amb altaveus)
- (1) Ordinador o ordinador portàtil
Pas 1: construïu el maquinari per al detector de notes musicals
Mitjançant un Arduino Uno, els cables de connexió, una placa sense soldar i un mòdul de detecció de so d'alta sensibilitat (o similar) del sensor de micròfon DEVMO construeixen el circuit que es mostra en aquesta imatge
Pas 2: programa el Detector de notes musicals
A l’IDE Arduino, afegiu el codi següent.
gistfile1.txt
/* |
Nom del fitxer / esbós: MusicalNoteDetector |
Número de versió: v1.0 Creat el 7 de juny de 2020 |
Autor original: Clyde A. Lettsome, PhD, PE, MEM |
Descripció: aquest codi / esbós mostra la freqüència aproximada i la nota musical reproduïda en un teclat electrònic o una aplicació de piano. Per a aquest projecte, la sortida analògica del fitxer |
El detector de mòduls de so s’envia a l’entrada analògica A0 de l’Arduino Uno. El senyal analògic es mostra i es quantifica (digitalitza). S’utilitza el codi d’autocorrelació, ponderació i afinació |
trobar freqüència fonamental utilitzant els primers 3 períodes. La freqüència fonamental aproximada es compara amb les freqüències de les octaves 3, 4 i 5 per determinar el musical més proper |
freqüència de notes. Finalment, la nota endevinada de la freqüència més propera s’imprimeix a la pantalla. |
Llicència: aquest programa és programari lliure; podeu redistribuir-lo i / o modificar-lo segons els termes de la Llicència Pública General GNU (GPL) versió 3, o qualsevol altra versió posterior |
versió que trieu, publicada per la Free Software Foundation. |
Notes: Copyright (c) 2020 de C. A. Lettsome Services, LLC |
Per obtenir més informació, visiteu |
*/ |
#define SAMPLES 128 // Max 128 per a Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 // Fs = Basat en Nyquist, ha de ser 2 vegades la freqüència més alta esperada. |
#define OFFSETSAMPLES 40 // s’utilitza amb finalitats calabradores |
#define TUNER -3 // Ajusta fins que C3 sigui 130,50 |
període de mostreig flotant; |
microSegons llargs sense signar; |
int X [MOSTRES]; // Creeu vector de MOSTRES de mida per contenir valors reals |
float autoCorr [MOSTRES]; // Creeu vector de MOSTRES de mida per mantenir valors imaginaris |
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 desplaçament |
int avgOffSet; // crear vector de desplaçament |
int i, k, periodEnd, periodBegin, period, ajust, noteLocation, octaveRange; |
float maxValue, minValue; |
suma llarga; |
int batre = 0; |
int numOfCycles = 0; |
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total; |
byte state_machine = 0; |
int samplesPerPeriod = 0; |
configuració nul·la () |
{ |
Serial.begin (115200); // 115200 Baud rate per al monitor de sèrie |
} |
bucle buit () |
{ |
//***************************************************************** |
// Secció de calabració |
//***************************************************************** |
Serial.println ("Calabrating. Si us plau, no toqueu cap nota durant la calabració."); |
per a (i = 0; i <OFFSETSAMPLES; i ++) |
{ |
offSet = analogRead (0); // Llegeix el valor del pin analògic 0 (A0), quantifiqueu-lo i deseu-lo com a terme real. |
//Serial.println(offSet); // utilitzeu això per ajustar el mòdul de detecció de so a aproximadament la meitat o 512 quan no es reprodueixi cap so. |
sumOffSet = sumOffSet + offSet ; |
} |
samplesPerPeriod = 0; |
Valor màxim = 0; |
//***************************************************************** |
// Prepareu-vos per acceptar l'entrada d'A0 |
//***************************************************************** |
avgOffSet = round (sumOffSet / OFFSETSAMPLES); |
Serial.println ("Compte enrere"); |
retard (1000); // pausa durant 1 segon |
Serial.println ("3"); |
retard (1000); // pausa durant 1 segon |
Serial.println ("2"); |
retard (1000); // pausa per a 1 |
Serial.println ("1"); |
retard (1000); // pausa durant 1 segon |
Serial.println ("Reprodueix la teva nota!"); |
retard (250); // Pausa durant 1/4 de segon durant el temps de reacció |
//***************************************************************** |
// Recolliu mostres de MOSTRES d'A0 amb el període de mostra del període de mostreig |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Període en microsegons |
per a (i = 0; i <SAMPLES; i ++) |
{ |
microSegons = micros (); // Retorna el nombre de microsegons des que la placa Arduino va començar a executar l'script actual. |
X = analogRead (0); // Llegeix el valor del pin analògic 0 (A0), quantifiqueu-lo i deseu-lo com a terme real. |
/ * temps d'espera restant entre mostres si és necessari en segons * / |
while (micros () <(microSeconds + (samplingPeriod * 1000000))) |
{ |
// no fer res només esperar |
} |
} |
//***************************************************************** |
// Funció d’autocorrelació |
//***************************************************************** |
for (i = 0; i <SAMPLES; i ++) // i = delay |
{ |
suma = 0; |
for (k = 0; k <SAMPLES - i; k ++) // Coincideix el senyal amb el senyal retardat |
{ |
suma = suma + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] és el senyal i X [k + i] és la versió retardada |
} |
autoCorr = suma / MOSTRES; |
// Primera màquina d'estat de detecció de pics |
if (state_machine == 0 && i == 0) |
{ |
batre = autoCorr * 0,5; |
màquina_estat = 1; |
} |
altrament si (state_machine == 1 && i> 0 && beat 0) // state_machine = 1, trobeu 1 període per utilitzar el primer cicle |
{ |
Valor màxim = autoCorr ; |
} |
else if (state_machine == 1 && i> 0 && batre <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodBegin = i-1; |
màquina_estat = 2; |
numOfCycles = 1; |
samplesPerPeriod = (períodeBegin - 0); |
període = samplesPerPeriod; |
ajustador = TUNER + (50,04 * exp (-0,102 * samplesPerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod)) - ajustador; // f = fs / N |
} |
altrament si (state_machine == 2 && i> 0 && batre 0) // state_machine = 2, trobeu 2 períodes per al 1r i 2n cicle |
{ |
Valor màxim = autoCorr ; |
} |
else if (state_machine == 2 && i> 0 && batre <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1; |
màquina_estat = 3; |
numOfCycles = 2; |
samplesPerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - ajustador; // f = (2 * fs) / (2 * N) |
Valor màxim = 0; |
} |
altrament si (state_machine == 3 && i> 0 && batre 0) // state_machine = 3, trobeu 3 períodes per al 1r, 2n i 3r cicle |
{ |
Valor màxim = autoCorr ; |
} |
else if (màquina_estat == 3 && i> 0 && batre <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1; |
màquina_estat = 4; |
numOfCycles = 3; |
samplesPerPeriod = (PeriodEnd - 0); |
signalFrequency3 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - ajustador; // f = (3 * fs) / (3 * N) |
} |
} |
//***************************************************************** |
// Anàlisi de resultats |
//***************************************************************** |
if (samplesPerPeriod == 0) |
{ |
Serial.println ("Hmm ….. No estic segur. Esteu intentant enganyar-me?"); |
} |
en cas contrari |
{ |
// prepara la funció de ponderació |
total = 0; |
if (freqüència del senyal! = 0) |
{ |
total = 1; |
} |
if (freqüència del senyal2! = 0) |
{ |
total = total + 2; |
} |
if (signalFrequency3! = 0) |
{ |
total = total + 3; |
} |
// calcular la freqüència mitjançant la funció de ponderació |
signalFrequencyGuess = ((1 / total) * signalFrequency) + ((2 / total) * signalFrequency2) + ((3 / total) * signalFrequency3); // trobar una freqüència ponderada |
Serial.print ("La nota que heu interpretat és aproximadament"); |
Serial.print (signalFrequencyGuess); // Imprimiu la suposició de freqüència. |
Serial.println ("Hz."); |
// trobar el rang d'octava basat en la suposició |
rang d’octava = 3; |
while (! (signalFrequencyGuess> = storageNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7)) |
{ |
per a (i = 0; i <12; i ++) |
{ |
storageNoteFreq = 2 * storageNoteFreq ; |
} |
octaveRange ++; |
} |
// Cerqueu la nota més propera |
Valor mínim = 10000000; |
notaLocalització = 0; |
per a (i = 0; i <12; i ++) |
{ |
if (MinValue> abs (signalFrequencyGuess-storedNoteFreq ))) |
{ |
MinValue = abs (signalFrequencyGuess-storedNoteFreq ); |
notaLocalització = i; |
} |
} |
// Imprimeix la nota |
Serial.print ("Crec que has jugat"); |
if (noteLocation == 0) |
{ |
Serial.print ("C"); |
} |
else if (noteLocation == 1) |
{ |
Serial.print ("C #"); |
} |
else if (noteLocation == 2) |
{ |
Serial.print ("D"); |
} |
else if (noteLocation == 3) |
{ |
Serial.print ("D #"); |
} |
else if (noteLocation == 4) |
{ |
Serial.print ("E"); |
} |
else if (noteLocation == 5) |
{ |
Serial.print ("F"); |
} |
else if (noteLocation == 6) |
{ |
Serial.print ("F #"); |
} |
else if (noteLocation == 7) |
{ |
Serial.print ("G"); |
} |
else if (noteLocation == 8) |
{ |
Serial.print ("G #"); |
} |
else if (noteLocation == 9) |
{ |
Serial.print ("A"); |
} |
else if (noteLocation == 10) |
{ |
Serial.print ("A #"); |
} |
else if (noteLocation == 11) |
{ |
Serial.print ("B"); |
} |
Serial.println (octaveRange); |
} |
//***************************************************************** |
//Atura't aquí. Feu clic al botó de reinici d'Arduino per reiniciar-lo |
//***************************************************************** |
mentre que (1); |
} |
visualitza rawgistfile1.txt allotjat amb ❤ per GitHub
Pas 3: configureu el detector de notes musicals
Connecteu l'Arduino Uno al PC amb el codi escrit o carregat a l'IDE Arduino. Compileu i pengeu el codi a Arduino. Col·loqueu el circuit a prop de la font de música. Nota: Al vídeo de presentació, faig servir una aplicació instal·lada a la tauleta juntament amb altaveus de PC com a font de música. Feu clic al botó de restabliment de la placa Arduino i, a continuació, reproduïu una nota a la font de música. Al cap d’uns segons, el Detector de notes musicals mostrarà la nota reproduïda i la seva freqüència.
Recomanat:
Llums de Nadal musicals automàtics de bricolatge (MSGEQ7 + Arduino): 6 passos (amb imatges)
Llums de Nadal musicals automàtics de bricolatge (MSGEQ7 + Arduino): de manera que cada any dic que faré això i que no m’aconseguiré mai fer-ho perquè posposo molt. El 2020 és un any de canvis, així que dic que és l’any per fer-ho. Així que espero que us agradi i creeu els vostres propis llums musicals de Nadal. Això serà un s
Bitlles musicals: 4 passos
Bitlles musicals: una cosa sobre ser avis és que sempre busqueu formes noves i emocionants d’entretenir els vostres meravellosos fills; i de tal manera que també us permeti jugar amb les vostres pròpies aficions. Introduïu el bitllet musical. Ús d'un ATTiny13 (b
Sabates MIDI musicals: 5 passos (amb imatges)
Sabates MIDI musicals: com moltes persones, sovint em trobo tocant inconscientment els peus, ja sigui per una cançó o per algun hàbit nerviós. Tanmateix, per divertit que sigui, sempre he sentit com si faltés alguna cosa. Si només pogués desencadenar els sons de dir, un
Arduino Music Notes Detector: 3 passos
Detector de notes musicals Arduino: la detecció de notes musicals des del senyal d’àudio és difícil de fer sobretot a Arduino a causa de la poca memòria i potència de processament. En general, la nota no és una ona sinusoïdal pura que dificulta la detecció. Si prenem la transformació de freqüència de va
Màquina d'impressions musicals d'aquesta nit: 7 passos
Màquina de rodes d’impressions musicals de Tonight Show: la màquina s’inspira en un segment de Tonight Show que va protagonitzar Jimmy Fallon anomenat “Wheel of Musical Impressions”. Primer premeu el botó de la caixa i us mostrarà una cançó i una cançó aleatòries al tauler LCD. Llavors has d'imitar