Inhoudsopgave:

Arduino Music Notes-detector - Ajarnpa
Arduino Music Notes-detector - Ajarnpa

Video: Arduino Music Notes-detector - Ajarnpa

Video: Arduino Music Notes-detector - Ajarnpa
Video: Arduino Music: Note Detector 2024, November
Anonim
Image
Image

Het detecteren van muzieknoten van het audiosignaal is moeilijk, vooral op Arduino vanwege het beperkte geheugen en de beperkte verwerkingskracht. Over het algemeen is de noot geen zuivere sinusgolf die de detectie bemoeilijkt. Als we de frequentietransformatie van verschillende muziekinstrumenten nemen, kan deze meerdere harmonischen bevatten op basis van de noot die wordt gespeeld. Elk instrument heeft zijn eigen kenmerkende combinatie van verschillende harmonischen. In deze code heb ik geprobeerd een programma te maken dat zoveel mogelijk instrumenten kan bestrijken. U kunt de bijgevoegde video raadplegen waarin ik heb geprobeerd de verschillende soorten instrumenten te testen, verschillende soorten tonen die door het toetsenbord worden gegenereerd en zelfs het geluid van de stem wordt gecontroleerd. De nauwkeurigheid van de detectie varieert van instrument tot instrument. Voor sommige instrumenten (bijv. piano) in een beperkt bereik (200-500Hz) is het nauwkeurig, terwijl het voor sommige instrumenten een lage nauwkeurigheid heeft (bijv. Harmonica).

Deze code maakt gebruik van een eerder ontwikkelde FFT-code genaamd EasyFFT.

De demonstratie van de code wordt getoond in de bovenstaande video met verschillende soorten instrumentgeluid en vocaal.

Benodigdheden

- Arduino Nano/Uno of hoger

- Microfoonmodule voor Arduino

Stap 1: Algoritme voor nootdetectie

Zoals vermeld in de vorige stap, is de detectie moeilijk vanwege de aanwezigheid van meerdere frequenties in de audiomonsters.

Het programma werkt in de volgende flow:

1. Data-acquisitie:

- deze sectie neemt 128 samples van audiogegevens, waarbij de scheiding tussen twee samples (samplefrequentie) afhankelijk is van de frequentie van interesse. In dit geval gebruiken we de ruimte tussen twee monsters om de Hann-vensterfunctie en de amplitude/RMS-berekening toe te passen. Deze code voert ook een ruwe nulstelling uit door 500 af te trekken van de analoge leeswaarde. Deze waarde kan indien nodig worden gewijzigd. Voor een typisch geval werken deze waarden goed. Verder moet er enige vertraging worden toegevoegd om een bemonsteringsfrequentie van ongeveer 1200 Hz te hebben. in het geval van een bemonsteringsfrequentie van 1200 Hz kan een maximale frequentie van 600 Hz worden gedetecteerd.

for(int i=0;i<128;i++) {a=analogRead(Mic_pin)-500; //ruwe nulverschuiving sum1=sum1+a; // naar gemiddelde waarde sum2=sum2+a*a; // naar RMS-waarde a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Hann-venster in = 4 * a; // schalen voor float naar int conversie delayMicroseconds (195); // gebaseerd op het frequentiebereik van de operatie}

2. FFT:

Zodra de gegevens gereed zijn, wordt FFT uitgevoerd met EasyFFT. Deze EasyFFT-functie is aangepast om FFT voor 128 samples te fixeren. De code is ook aangepast om het geheugengebruik te verminderen. De originele EasyFFT-functie is ontworpen om tot 1028 samples te hebben (met het compatibele board), terwijl we maar 128 samples nodig hebben. deze code vermindert het geheugenverbruik met ongeveer 20% in vergelijking met de originele EasyFFT-functie.

Zodra FFT is voltooid, retourneert de code de top 5 van meest dominante frequentiepieken voor verdere analyse. Deze frequenties zijn gerangschikt in afnemende volgorde van amplitude.

3. Voor elke piek detecteert de code mogelijke noten die ermee verbonden zijn. deze code scant alleen tot 1200 Hz. Het is niet nodig om hetzelfde te hebben als de frequentie met maximale amplitude.

Alle frequenties worden in kaart gebracht tussen 0 en 255, hier wordt het eerste octaaf gedetecteerd, bijvoorbeeld 65,4 Hz tot 130,8 vertegenwoordigt een octaaf, 130,8 Hz tot 261,6 Hz vertegenwoordigt een andere. Voor elk octaaf worden frequenties in kaart gebracht van 0 tot 255. hier in kaart gebracht vanaf C tot C'.

if(f_peaks>1040){f_peaks=0;} if(f_peaks>=65.4 && f_peaks=130.8 && f_peaks=261.6 && f_peaks=523.25 && f_peaks =1046 && f_peaks<=2093) {f_peaks=255*((f_peaks/1046)-1);}

NoteV-arraywaarden worden gebruikt om de noot toe te wijzen aan de gedetecteerde frequenties.

byte NoteV[13]={8, 23, 40, 57, 76, 96, 116, 138, 162, 187, 213, 241, 255};

4. Na het berekenen van de noot voor elke frequentie kan het zijn dat er meerdere frequenties bestaan die dezelfde noot suggereren. Om een nauwkeurige uitvoercode te hebben, wordt ook rekening gehouden met herhalingen. De code telt alle frequentiewaarden op op basis van amplitudevolgorde en herhalingen en piekt de noot met maximale amplitude.

Stap 2: Toepassing

Het gebruik van de code is eenvoudig, maar er zijn ook meerdere beperkingen waarmee u rekening moet houden. De code kan worden gekopieerd omdat deze wordt gebruikt voor nootdetectie. De onderstaande punten moeten worden overwogen tijdens het gebruik ervan.

1. Pintoewijzing:

Op basis van de bijgevoegde Pin moet de toewijzing worden aangepast. Voor mijn experiment hield ik het op analoge pin 7, void setup() {Serial.begin(250000); Mic_pin = A7; }

2. Microfoongevoeligheid:

De gevoeligheid van de microfoon moet worden aangepast, een dergelijke golfvorm kan met een goede amplitude worden gegenereerd. Meestal wordt de microfoonmodule geleverd met een gevoeligheidsinstelling. de juiste gevoeligheid moet worden geselecteerd, zodat het signaal niet te klein is en ook niet afknipt vanwege een hogere amplitude.

3. Amplitudedrempel:

Deze code wordt alleen geactiveerd als de signaalamplitude hoog genoeg is. deze instelling moet handmatig door de gebruiker worden ingesteld. deze waarde hangt af van de gevoeligheid van de microfoon en van de toepassing.

if(sum2-sum1>5){

..

in de bovenstaande code geeft som2 de RMS-waarde, terwijl som 1 de gemiddelde waarde geeft. dus het verschil tussen deze twee waarden geeft de amplitude van het geluidssignaal. in mijn geval werkt het goed met een amplitudewaarde van ongeveer 5.

4. Standaard drukt deze code de gedetecteerde notitie af. als u echter van plan bent de notitie voor een ander doel te gebruiken, moet het direct toegewezen nummer worden gebruikt. bijvoorbeeld C=0;C#=1, D=2, D#=3 en verder.

5. Als het instrument een hogere frequentie heeft, kan de code een valse output geven. de maximale frequentie wordt beperkt door de bemonsteringsfrequentie. dus u kunt rond de vertragingswaarden spelen om een optimale uitvoer te krijgen. in onderstaande codevertraging van 195 microseconden. die kan worden aangepast om een optimale output te krijgen. Dit heeft invloed op de totale uitvoeringstijd.

{a=analogRead(Mic_pin)-500; //ruwe nulverschuiving

som1=som1+a; // naar gemiddelde waarde sum2=sum2+a*a; // naar RMS-waarde a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Hann-venster in = 4 * a; // schalen voor float naar int conversie delayMicroseconds (195); // gebaseerd op het frequentiebereik van de operatie}

6. deze code werkt alleen tot 2000Hz frequentie. door de vertraging tussen de bemonstering te elimineren, kan ongeveer 3-4 kHz aan bemonsteringsfrequenties worden verkregen.

Preventieve maatregelen:

  • Zoals vermeld in de EasyFFT-tutorial, vreet de FFT een enorme hoeveelheid geheugen van Arduino op. Dus als je een programma hebt dat een aantal waarden moet opslaan, is het aan te raden om een bord met meer geheugen te gebruiken.
  • Deze code kan goed werken voor het ene instrument/zanger en slecht voor het andere. Realtime Nauwkeurige detectie is niet mogelijk vanwege rekenkundige beperkingen.

Stap 3: Zomers

Het detecteren van noten is rekenintensief werk, het verkrijgen van real-time output is erg moeilijk, vooral op Arduino. Deze code kan ongeveer 6,6 samples /seconden geven (voor 195 microseconden vertraging toegevoegd). deze code werkt goed met de piano en sommige andere instrumenten.

Ik hoop dat deze code en tutorial nuttig zijn in uw project met betrekking tot muziek. in geval van twijfel of suggestie voel je vrij om commentaar of een bericht te sturen.

In de komende tutorial zal ik deze code aanpassen voor het detecteren van muziekakkoorden. dus blijf op de hoogte.

Aanbevolen: