Indholdsfortegnelse:

Musiknote -detektor: 3 trin
Musiknote -detektor: 3 trin

Video: Musiknote -detektor: 3 trin

Video: Musiknote -detektor: 3 trin
Video: Trip to Bandung Indonesia EP2 Tangkuban Perahu & Saung Angklung Udjo----The volcano, The Angklung 2024, November
Anonim
Image
Image

Forundre dine venner og familie med dette projekt, der registrerer den tone, der spilles af et instrument. Dette projekt viser den omtrentlige frekvens samt den musikalske note, der spilles på et elektronisk keyboard, klaverapp eller et andet instrument.

detaljer

For dette projekt sendes den analoge udgang fra lydmoduldetektoren til A0 analogindgangen på Arduino Uno. Det analoge signal samples og kvantiseres (digitaliseres). Autokorrelation, vægtning og tuningskode bruges til at finde grundlæggende frekvens ved hjælp af de første 3 perioder. Den omtrentlige grundfrekvens sammenlignes derefter med frekvenser i oktaverne 3, 4 og 5 for at bestemme den nærmeste musiknote -frekvens. Endelig udskrives den gættede note for den nærmeste frekvens til skærmen.

Bemærk: Denne instruktion fokuserer kun på, hvordan man bygger projektet. For mere information om detaljerne og designmæssige begrundelser, besøg dette link: Flere oplysninger

Forbrugsvarer

  • (1) Arduino Uno (eller Genuino Uno)
  • (1) DEVMO mikrofonsensor Kompatibel med høj følsomhed Lyddetekteringsmodul
  • (1) Loddefrit brødbræt
  • (1) USB-A til B-kabel
  • Jumper ledninger
  • Musikalsk kilde (klaver, tastatur eller paino -app med højttalere)
  • (1) Computer eller bærbar computer

Trin 1: Konstruer hardware til Musical Note Detector

Indstil Musical Note Detector
Indstil Musical Note Detector

Ved hjælp af en Arduino Uno konstruerer forbindelsestråde, et loddet brødbræt og et DEVMO mikrofonsensor højfølsom lyddetektionsmodul (eller lignende) det kredsløb, der er vist i dette billede

Trin 2: Programmer Musical Note Detector

I Arduino IDE skal du tilføje følgende kode.

gistfile1.txt

/*
Fil-/skitsenavn: MusicalNoteDetector
Versionsnr.: v1.0 Oprettet 7. juni 2020
Oprindelig forfatter: Clyde A. Lettsome, PhD, PE, MEM
Beskrivelse: Denne kode/skitse viser den omtrentlige frekvens samt den musikalske note, der spilles på et elektronisk keyboard eller klaverapp. For dette projekt er det analoge output fra
lydmodul detektor sendes til A0 analog indgang på Arduino Uno. Det analoge signal samples og kvantiseres (digitaliseres). Autokorrelation, vægtning og tuningskode bruges til at
finde grundlæggende frekvens ved hjælp af de første 3 perioder. Den omtrentlige grundfrekvens sammenlignes derefter med frekvenser i oktaverne 3, 4 og 5 for at bestemme den nærmeste musical
bemærk frekvens. Endelig udskrives den gættede note for den nærmeste frekvens til skærmen.
Licens: Dette program er gratis software; du kan omfordele det og/eller ændre det under vilkårene i GNU General Public License (GPL) version 3 eller senere
version efter eget valg, som udgivet af Free Software Foundation.
Bemærkninger: Copyright (c) 2020 af C. A. Lettsome Services, LLC
For mere information besøg
*/
#define PRØVER 128 // Max 128 til Arduino Uno.
#define SAMPLING_FREQUENCY 2048 // Fs = Baseret på Nyquist, skal være 2 gange den højeste forventede frekvens.
#define OFFSETSAMPLES 40 // bruges til kalibreringsformål
#define TUNER -3 // Juster indtil C3 er 130,50
float samplingPeriod;
usignerede lange microSeconds;
int X [PRØVER]; // opret en vektor af størrelsesprøver for at holde reelle værdier
float autoCorr [PRØVER]; // opret en vektor af størrelsesprøver for at holde imaginære værdier
float lagretNoteFreq [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]; // opret offsetvektor
int avgOffSet; // opret offsetvektor
int i, k, periodEnd, periodBegin, period, justerer, noteLocation, octaveRange;
float maxValue, minValue;
lang sum;
int tærskning = 0;
int numOfCycles = 0;
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total;
byte state_machine = 0;
int samplesPerPeriod = 0;
ugyldig opsætning ()
{
Serial.begin (115200); // 115200 Baud rate for den serielle monitor
}
hulrum ()
{
//*****************************************************************
// Kalibreringssektion
//*****************************************************************
Serial.println ("Kalibrering. Spil venligst ingen noter under kalibrering.");
for (i = 0; i <OFFSETSAMPLES; i ++)
{
offSet = analogRead (0); // Læser værdien fra analog pin 0 (A0), kvantificerer den og gemmer den som et reelt udtryk.
//Serial.println(offSet [ii]); // brug dette til at justere lyddetektionsmodulet til cirka halvdelen eller 512, når der ikke afspilles nogen lyd.
sumOffSet = sumOffSet + offSet ;
}
samplesPerPeriod = 0;
maxVærdi = 0;
//*****************************************************************
// Forbered dig på at acceptere input fra A0
//*****************************************************************
avgOffSet = round (sumOffSet / OFFSETSAMPLES);
Serial.println ("Nedtælling.");
forsinkelse (1000); // pause i 1 sekund
Serial.println ("3");
forsinkelse (1000); // pause i 1 sekund
Serial.println ("2");
forsinkelse (1000); // pause i 1
Serial.println ("1");
forsinkelse (1000); // pause i 1 sekund
Serial.println ("Spil din note!");
forsinkelse (250); // pause i 1/4 sekund for reaktionstid
//*****************************************************************
// Saml prøver af prøver fra A0 med prøveperiode for prøveudtagning
//*****************************************************************
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Periode i mikrosekunder
for (i = 0; i <SAMPLES; i ++)
{
microSeconds = micros (); // Returnerer antallet af mikrosekunder siden Arduino -kortet begyndte at køre det aktuelle script.
X = analogRead (0); // Læser værdien fra analog pin 0 (A0), kvantificerer den og gemmer den som et reelt udtryk.
/ *resterende ventetid mellem prøver om nødvendigt i sekunder */
mens (micros () <(microSeconds + (samplingPeriod * 1000000)))
{
// gør ingenting bare vent
}
}
//*****************************************************************
// Autokorrelationsfunktion
//*****************************************************************
for (i = 0; i <SAMPLES; i ++) // i = forsinkelse
{
sum = 0;
for (k = 0; k <SAMPLES - i; k ++) // Match signal med forsinket signal
{
sum = sum + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] er signalet og X [k+i] er den forsinkede version
}
autoCorr = sum / PRØVER;
// First Peak Detect State Machine
hvis (state_machine == 0 && i == 0)
{
tærske = autoCorr * 0,5;
state_machine = 1;
}
ellers hvis (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, find 1 periode for brug af første cyklus
{
maxValue = autoCorr ;
}
ellers hvis (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);
periode = samplesPerPeriod;
justerer = TUNER+(50.04 * exp (-0.102 * samplesPerPeriod));
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod))-justerer; // f = fs/N
}
ellers hvis (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, find 2 perioder for 1. og 2. cyklus
{
maxValue = autoCorr ;
}
ellers hvis (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
tilstand_maskine = 3;
numOfCycles = 2;
samplesPerPeriod = (periodEnd - 0);
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-justerer; // f = (2*fs)/(2*N)
maxVærdi = 0;
}
ellers hvis (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, find 3 perioder for 1., 2. og 3. cyklus
{
maxValue = autoCorr ;
}
ellers hvis (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0)
{
periodEnd = i-1;
tilstand_maskine = 4;
numOfCycles = 3;
samplesPerPeriod = (periodEnd - 0);
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-justerer; // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// Resultatanalyse
//*****************************************************************
hvis (samplesPerPeriod == 0)
{
Serial.println ("Hmm ….. Jeg er ikke sikker. Prøver du at narre mig?");
}
andet
{
// forberede vægtningsfunktionen
i alt=0;
hvis (signalFrekvens! = 0)
{
i alt=1;
}
hvis (signalFrequency2! = 0)
{
total = i alt + 2;
}
hvis (signalFrequency3! = 0)
{
total = i alt + 3;
}
// beregne frekvensen ved hjælp af vægtningsfunktionen
signalFrequencyGuess = ((1/total) * signalFrequency) + ((2/total) * signalFrequency2) + ((3/total) * signalFrequency3); // find en vægtet frekvens
Serial.print ("Den note du spillede er cirka");
Serial.print (signalFrequencyGuess); // Udskriv frekvensgættet.
Serial.println ("Hz.");
// find oktavinterval baseret på gætte
octaveRange = 3;
mens (! (signalFrequencyGuess> = storageNoteFreq [0] -7 && signalFrequencyGuess <= storageNoteFreq [11] +7))
{
for (i = 0; i <12; i ++)
{
storageNoteFreq = 2 * lagretNoteFreq ;
}
octaveRange ++;
}
// Find den nærmeste note
minVærdi = 10000000;
noteLocation = 0;
for (i = 0; i <12; i ++)
{
hvis (minValue> abs (signalFrequencyGuess-storedNoteFreq ))
{
minValue = abs (signalFrequencyGuess-storedNoteFreq );
noteLocation = i;
}
}
// Udskriv sedlen
Serial.print ("Jeg tror du spillede");
hvis (noteLocation == 0)
{
Serial.print ("C");
}
ellers hvis (noteLocation == 1)
{
Serial.print ("C#");
}
ellers hvis (noteLocation == 2)
{
Serial.print ("D");
}
ellers hvis (noteLocation == 3)
{
Serial.print ("D#");
}
ellers hvis (noteLocation == 4)
{
Serial.print ("E");
}
ellers hvis (noteLocation == 5)
{
Serial.print ("F");
}
ellers hvis (noteLocation == 6)
{
Serial.print ("F#");
}
ellers hvis (noteLocation == 7)
{
Serial.print ("G");
}
ellers hvis (noteLocation == 8)
{
Serial.print ("G#");
}
ellers hvis (noteLocation == 9)
{
Serial.print ("A");
}
ellers hvis (noteLocation == 10)
{
Serial.print ("A#");
}
ellers hvis (noteLocation == 11)
{
Serial.print ("B");
}
Serial.println (octaveRange);
}
//*****************************************************************
//Stop her. Tryk på nulstillingsknappen på Arduino for at genstarte
//*****************************************************************
mens (1);
}

se rawgistfile1.txt hostet af ❤ af GitHub

Trin 3: Konfigurer Musical Note Detector

Tilslut Arduino Uno til pc'en med koden skrevet eller indlæst i Arduino IDE. Kompilér og upload koden til Arduino. Placer kredsløbet tæt på musikkilden. Bemærk: I introduktionsvideoen bruger jeg en app installeret på tablet sammen med pc -højttalere som min musikkilde. Tryk på nulstillingsknappen på Arduino Board, og afspil derefter en note om musikkilden. Efter et par sekunder viser Musical Note Detector den spillede note og dens frekvens.

Anbefalede: