Obsah:

Detektor hudební noty: 3 kroky
Detektor hudební noty: 3 kroky

Video: Detektor hudební noty: 3 kroky

Video: Detektor hudební noty: 3 kroky
Video: Snadná improvizace na piano na 3 akordy i pro úplné začátečníky 2024, Listopad
Anonim
Image
Image

Ohromte své přátele a rodinu tímto projektem, který detekuje noty zahrané nástrojem. Tento projekt zobrazí přibližnou frekvenci a noty hrané na elektronické klávesnici, klavírní aplikaci nebo jiném nástroji.

Podrobnosti

U tohoto projektu je analogový výstup z detektoru zvukového modulu odeslán na analogový vstup A0 Arduino Uno. Analogový signál je vzorkován a kvantován (digitalizován). Autokorelační, váhovací a ladicí kód se používá k nalezení základní frekvence pomocí prvních 3 období. Přibližná základní frekvence se pak porovná s frekvencemi v oktávách 3, 4 a 5, aby se určila nejbližší frekvence noty. Nakonec se na obrazovku vytiskne uhodnutá poznámka pro nejbližší frekvenci.

Poznámka: Tato instruktáž se zaměřuje pouze na to, jak sestavit projekt. Další informace o podrobnostech a zdůvodněních návrhu naleznete na tomto odkazu: Další informace

Zásoby

  • (1) Arduino Uno (nebo Genuino Uno)
  • (1) Modul detekce zvuku DEVMO pro mikrofon kompatibilní s vysokou citlivostí
  • (1) Bezpájecí prkénko
  • (1) Kabel USB-A na B
  • Propojovací vodiče
  • Hudební zdroj (aplikace pro klavír, klávesnici nebo Paino s reproduktory)
  • (1) Počítač nebo notebook

Krok 1: Vytvořte hardware pro detektor hudební noty

Nastavte detektor hudební noty
Nastavte detektor hudební noty

Pomocí Arduino Uno, propojovacích vodičů, nepájivé desky a DEVMO mikrofonního senzoru High Sensitivity Sound Detection Module (nebo podobného) sestrojte obvod zobrazený na tomto obrázku

Krok 2: Naprogramujte detektor hudební noty

Do Arduino IDE přidejte následující kód.

gistfile1.txt

/*
Název souboru/skici: MusicalNoteDetector
Číslo verze: v1.0 Vytvořeno 7. června 2020
Původní autor: Clyde A. Lettsome, PhD, PE, MEM
Popis: Tento kód/skica zobrazuje přibližnou frekvenci a hudební notu přehrávanou na elektronické klávesnici nebo klavíru. Pro tento projekt je analogový výstup z
detektor zvukového modulu je odeslán na analogový vstup A0 Arduino Uno. Analogový signál je vzorkován a kvantován (digitalizován). K tomu se používá autokorelace, váha a ladicí kód
najděte základní frekvenci pomocí prvních 3 období. Přibližná základní frekvence se pak porovná s frekvencemi v oktávách 3, 4 a 5, aby se určil nejbližší muzikál
poznámka frekvence. Nakonec se na obrazovku vytiskne uhodnutá poznámka pro nejbližší frekvenci.
Licence: Tento program je svobodný software; můžete jej znovu distribuovat a/nebo upravovat podle podmínek GNU General Public License (GPL) verze 3 nebo kdykoli později
verze podle vašeho výběru, vydaná Free Software Foundation.
Poznámky: Copyright (c) 2020 by C. A. Lettsome Services, LLC
Pro více informací navštivte
*/
#define VZORKY 128 // Max 128 pro Arduino Uno.
#define SAMPLING_FREQUENCY 2048 // Fs = Na základě Nyquistu musí být 2krát nejvyšší očekávaná frekvence.
#define OFFSETSAMPLES 40 // používané pro účely kalibrace
#define TUNER -3 // Upravujte, dokud C3 není 130,50
plovoucí vzorkování Období;
nepodepsané dlouhé mikrosekundy;
int X [VZORKY]; // vytvoření vektoru velikosti SAMPLES pro uchování skutečných hodnot
float autoCorr [VZORKY]; // vytvoření vektoru velikosti SAMPLES pro uložení imaginárních hodnot
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]; // vytvoření ofsetového vektoru
int avgOffSet; // vytvoření ofsetového vektoru
int i, k, periodEnd, periodBegin, period, adjuster, noteLocation, octaveRange;
float maxValue, minValue;
dlouhá částka;
int mlátit = 0;
int numOfCycles = 0;
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total;
byte state_machine = 0;
int vzorkyPerPeriod = 0;
neplatné nastavení ()
{
Serial.begin (115200); // 115200 Baud rate pro Serial Monitor
}
prázdná smyčka ()
{
//*****************************************************************
// Sekce kalibrace
//*****************************************************************
Serial.println („Calabrating. Během kalibrace prosím nehrajte žádné noty.“);
pro (i = 0; i <OFFSETSAMPLES; i ++)
{
offSet = analogRead (0); // Přečte hodnotu z analogového pinu 0 (A0), kvantifikuje ji a uloží jako skutečný výraz.
//Serial.println(offSet); // použijte k nastavení modulu detekce zvuku na přibližně polovinu nebo 512, pokud není přehráván žádný zvuk.
sumOffSet = sumOffSet + offSet ;
}
samplePerPeriod = 0;
maxValue = 0;
//*****************************************************************
// Připravte se na přijetí vstupu z A0
//*****************************************************************
avgOffSet = kulatý (sumOffSet / OFFSETSAMPLES);
Serial.println ("Odpočítávání.");
zpoždění (1000); // pauza na 1 sekundu
Serial.println ("3");
zpoždění (1000); // pauza na 1 sekundu
Serial.println ("2");
zpoždění (1000); // pauza na 1
Serial.println ("1");
zpoždění (1000); // pauza na 1 sekundu
Serial.println („Zahrajte si poznámku!“);
zpoždění (250); // doba reakce na 1/4 sekundy
//*****************************************************************
// Sbírejte vzorky SAMPLES z A0 s periodou vzorkování Perioda vzorkování
//*****************************************************************
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Období v mikrosekundách
pro (i = 0; i <VZORKY; i ++)
{
microSeconds = micros (); // Vrátí počet mikrosekund od doby, kdy na desce Arduino začal běžet aktuální skript.
X = analogové čtení (0); // Přečte hodnotu z analogového pinu 0 (A0), kvantifikuje ji a uloží jako skutečný výraz.
/ *zbývající čekací doba mezi vzorky v případě potřeby v sekundách */
while (micros () <(microSeconds + (samplingPeriod * 1000000))))
{
// nedělej nic, jen čekej
}
}
//*****************************************************************
// Funkce autokorelace
//*****************************************************************
for (i = 0; i <SAMPLES; i ++) // i = zpoždění
{
součet = 0;
for (k = 0; k <SAMPLES - i; k ++) // Shoda signálu se zpožděným signálem
{
součet = součet + ((((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] je signál a X [k+i] je zpožděná verze
}
autoCorr = součet / VZORKY;
// První stav detekce vrcholu
if (state_machine == 0 && i == 0)
{
thresh = autoCorr * 0,5;
state_machine = 1;
}
else if (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, find 1 period for using first cycle
{
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;
samplePerPeriod = (periodBegin - 0);
period = samplePerPeriod;
nastavovač = TUNER+(50,04 * exp (-0,102 * samplePerPeriod));
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-nastavovač; // f = fs/N
}
else if (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, find 2 period for 1st and 2nd cycle
{
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;
samplePerPeriod = (periodEnd - 0);
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-nastavovač; // f = (2*fs)/(2*N)
maxValue = 0;
}
else if (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, find 3 period for 1st, 2nd and 3rd cycle
{
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;
samplePerPeriod = (periodEnd - 0);
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-nastavovač; // f = (3*fs)/(3*N)
}
}
//*****************************************************************
// Analýza výsledků
//*****************************************************************
pokud (samplePerPeriod == 0)
{
Serial.println („Hmm….. nejsem si jistý. Snažíš se mě oklamat?“);
}
jiný
{
// připravte funkci vážení
celkem = 0;
if (signalFrequency! = 0)
{
celkem = 1;
}
if (signalFrequency2! = 0)
{
celkem = celkem + 2;
}
if (signalFrequency3! = 0)
{
celkem = celkem + 3;
}
// vypočítat frekvenci pomocí funkce vážení
signalFrequencyGuess = ((1/celkem) * signalFrequency) + ((2/celkem) * signalFrequency2) + ((3/celkem) * signalFrequency3); // najděte váženou frekvenci
Serial.print („Poznámka, kterou jste zahráli, je přibližně“);
Serial.print (signalFrequencyGuess); // Vytiskněte odhad frekvence.
Serial.println ("Hz.");
// najděte rozsah oktáv na základě odhadu
octaveRange = 3;
while (! (signalFrequencyGuess> = uloženoNoteFreq [0] -7 && signalFrequencyGuess <= uloženéNoteFreq [11] +7))
{
pro (i = 0; i <12; i ++)
{
uloženéNoteFreq = 2 * uloženéNoteFreq ;
}
octaveRange ++;
}
// Najděte nejbližší poznámku
minHodnota = 10 000 000;
noteLocation = 0;
pro (i = 0; i <12; i ++)
{
if (minValue> abs (signalFrequencyGuess-storedNoteFreq ))
{
minValue = abs (signalFrequencyGuess-storedNoteFreq );
noteLocation = i;
}
}
// Vytiskněte poznámku
Serial.print („Myslím, že jsi hrál“);
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);
}
//*****************************************************************
//Zastavte tady. Restartujte stisknutím tlačítka reset na Arduinu
//*****************************************************************
zatímco (1);
}

zobrazit rawgistfile1.txt hostovaný s ❤ od GitHub

Krok 3: Nastavení detektoru hudební noty

Připojte Arduino Uno k počítači pomocí kódu zapsaného nebo načteného v Arduino IDE. Zkompilujte a nahrajte kód do Arduina. Umístěte obvod v blízkosti zdroje hudby. Poznámka: V úvodním videu používám jako zdroj hudby aplikaci nainstalovanou v tabletu ve spojení s reproduktory PC. Stiskněte tlačítko reset na desce Arduino a poté si zahrajte notu ve zdroji hudby. Po několika sekundách detektor hudebních not zobrazí přehrávanou notu a její frekvenci.

Doporučuje: