Inhaltsverzeichnis:

Arduino Musiknoten-Detektor - Gunook
Arduino Musiknoten-Detektor - Gunook

Video: Arduino Musiknoten-Detektor - Gunook

Video: Arduino Musiknoten-Detektor - Gunook
Video: Arduino Wireless Weather Station Project 2024, November
Anonim
Image
Image

Das Erkennen von Musiknoten aus dem Audiosignal ist insbesondere bei Arduino aufgrund des begrenzten Speichers und der begrenzten Verarbeitungsleistung schwierig. Im Allgemeinen handelt es sich bei der Note nicht um eine reine Sinuswelle, die die Erkennung erschwert. Wenn wir die Frequenztransformation verschiedener Musikinstrumente nehmen, kann sie basierend auf der gespielten Note mehrere Harmonische enthalten. Jedes Instrument hat seine eigene charakteristische Kombination verschiedener Obertöne. In diesem Code habe ich versucht, ein Programm zu erstellen, das so viele Instrumente wie möglich abdecken kann. Sie können sich das angehängte Video ansehen, in dem ich versucht habe, die verschiedenen Arten von Instrumenten, verschiedene Arten von Tönen, die von der Tastatur erzeugt werden, und sogar den Klang der Stimme zu testen. Die Genauigkeit der Erkennung variiert von Instrument zu Instrument. Bei einigen Instrumenten (z. B. Klavier) ist sie in einem begrenzten Bereich (200-500 Hz) genau, während sie bei einigen Instrumenten eine geringe Genauigkeit hat (z. B. Mundharmonika).

Dieser Code verwendet einen zuvor entwickelten FFT-Code namens EasyFFT.

Die Demonstration des Codes wird im obigen Video mit verschiedenen Arten von Instrumentenklang sowie Gesang gezeigt.

Lieferungen

- Arduino Nano/Uno oder höher

- Mikrofonmodul für Arduino

Schritt 1: Algorithmus zur Notenerkennung

Wie im vorherigen Schritt erwähnt, ist die Erkennung aufgrund des Vorhandenseins mehrerer Frequenzen in den Audiosamples schwierig.

Das Programm arbeitet in folgendem Ablauf:

1. Datenerfassung:

- Dieser Abschnitt nimmt 128 Samples aus Audiodaten, wobei die Trennung zwischen zwei Samples (Sampling-Frequenz) von der interessierenden Frequenz abhängt. In diesem Fall verwenden wir den Abstand zwischen zwei Abtastwerten, um die Hann-Fensterfunktion sowie die Amplituden-/RMS-Berechnung anzuwenden. Dieser Code führt auch eine grobe Nullung durch, indem er 500 vom analogread-Wert subtrahiert. Dieser Wert kann bei Bedarf geändert werden. Für einen typischen Fall funktionieren diese Werte gut. Außerdem muss eine gewisse Verzögerung hinzugefügt werden, um eine Abtastfrequenz von etwa 1200 Hz zu haben. bei 1200Hz Abtastfrequenz kann maximal eine Frequenz von 600 Hz erkannt werden.

for(int i=0;i<128;i++) { a=analogRead (Mic_pin)-500; // grobe Nullverschiebung sum1 = sum1 + a; //zum Durchschnittswert sum2=sum2+a*a; // zum Effektivwert a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Hann-Fenster in=4*a; // Skalierung für die Umwandlung von Float in Int delayMicroseconds(195); // basierend auf dem Betriebsfrequenzbereich }

2. FFT:

Sobald die Daten bereit sind, wird die FFT mit EasyFFT durchgeführt. Diese EasyFFT-Funktion wurde modifiziert, um die FFT für 128 Samples zu fixieren. Der Code wird auch modifiziert, um den Speicherverbrauch zu reduzieren. Die ursprüngliche EasyFFT-Funktion ist für bis zu 1028 Samples ausgelegt (mit dem kompatiblen Board), während wir nur 128 Samples benötigen. Dieser Code reduziert den Speicherverbrauch um etwa 20 % im Vergleich zur ursprünglichen EasyFFT-Funktion.

Sobald die FFT abgeschlossen ist, gibt der Code die 5 dominantesten Frequenzspitzen zur weiteren Analyse zurück. Diese Frequenzen sind in absteigender Amplitudenreihenfolge angeordnet.

3. Für jeden Peak erkennt der Code mögliche damit verbundene Noten. dieser Code scannt nur bis 1200 Hz. Es ist nicht erforderlich, die gleiche Frequenz wie die maximale Amplitude zu notieren.

Alle Frequenzen werden zwischen 0 und 255 abgebildet, hier wird die erste Oktave erkannt, beispielsweise 65,4 Hz bis 130,8 stellen eine Oktave dar, 130,8 Hz bis 261,6 Hz eine andere. Für jede Oktave werden Frequenzen von 0 bis 255 abgebildet. Hier beginnt die Zuordnung von C bis 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-Array-Werte werden verwendet, um die Note den erkannten Frequenzen zuzuordnen.

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

4. Nach der Berechnung der Note für jede Frequenz kann es vorkommen, dass mehrere Frequenzen existieren, die auf dieselbe Note schließen lassen. Um einen genauen Ausgabecode zu haben, werden auch Wiederholungen berücksichtigt. Der Code addiert alle Frequenzwerte basierend auf Amplitudenreihenfolge und Wiederholungen und hebt die Note mit maximaler Amplitude an.

Schritt 2: Bewerbung

Die Verwendung des Codes ist unkompliziert, es gibt jedoch auch mehrere Einschränkungen, die dabei beachtet werden müssen. Der Code kann kopiert werden, da er für die Notenerkennung verwendet wird. Die folgenden Punkte müssen bei der Verwendung beachtet werden.

1. Pinbelegung:

Basierend auf der beigefügten Pin-Belegung muss geändert werden. Für mein Experiment habe ich es auf Analog Pin 7 belassen.

Void setup () {Serial.begin(250000); Mikrofon_Pin = A7; }

2. Mikrofonempfindlichkeit:

Die Mikrofonempfindlichkeit muss modifiziert werden, so dass eine Wellenform mit guter Amplitude erzeugt werden kann. Meistens verfügt das Mikrofonmodul über eine Empfindlichkeitseinstellung. entsprechende Empfindlichkeit so zu wählen, dass das Signal weder zu klein ist noch durch höhere Amplitude abschneidet.

3. Amplitudenschwelle:

Dieser Code wird nur aktiviert, wenn die Signalamplitude hoch genug ist. Diese Einstellung muss vom Benutzer manuell vorgenommen werden. dieser Wert hängt sowohl von der Mikrofonempfindlichkeit als auch von der Anwendung ab.

if(sum2-sum1>5){

..

im obigen Code gibt Summe2 den RMS-Wert, während Summe 1 den Mittelwert angibt. die Differenz zwischen diesen beiden Werten ergibt die Amplitude des Tonsignals. in meinem Fall funktioniert es mit einem Amplitudenwert von etwa 5.

4. Standardmäßig druckt dieser Code die erkannte Notiz. Wenn Sie die Notiz jedoch für einen anderen Zweck verwenden möchten, sollte die direkt zugewiesene Nummer verwendet werden. zum Beispiel C=0;C#=1, D=2, D#=3 und weiter.

5. Wenn das Instrument eine höhere Frequenz hat, kann der Code eine falsche Ausgabe liefern. die maximale Frequenz wird durch die Abtastfrequenz begrenzt. Sie können also unterhalb der Verzögerungswerte herumspielen, um eine optimale Ausgabe zu erzielen. unten Codeverzögerung von 195 Mikrosekunden. die optimiert werden können, um eine optimale Ausgabe zu erzielen. Dies wirkt sich auf die Gesamtausführungszeit aus.

{ a=analogRead (Mic_pin)-500; // grobe Nullpunktverschiebung

sum1=sum1+a; //zum Durchschnittswert sum2=sum2+a*a; // zum Effektivwert a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // Hann-Fenster in=4*a; // Skalierung für die Umwandlung von Float in Int delayMicroseconds(195); // basierend auf dem Betriebsfrequenzbereich }

6. Dieser Code funktioniert nur bis 2000 Hz Frequenz. durch Eliminieren der Verzögerung zwischen den Abtastungen können etwa 3-4 kHz Abtastfrequenzen erhalten werden.

Vorsichtsmaßnahmen:

  • Wie im EasyFFT-Tutorial erwähnt, frisst die FFT eine riesige Menge an Speicher von Arduino. Wenn Sie also ein Programm haben, das einige Werte speichern muss, wird empfohlen, eine Karte mit mehr Speicher zu verwenden.
  • Dieser Code kann für ein Instrument/Sänger gut funktionieren und für einen anderen schlecht. Eine genaue Erkennung in Echtzeit ist aufgrund von Rechenbeschränkungen nicht möglich.

Schritt 3: Sommerlich

Die Notenerkennung ist rechenintensiv, eine Echtzeitausgabe ist besonders auf Arduino sehr schwierig. Dieser Code kann ungefähr 6,6 Samples/Sekunden ergeben (für eine Verzögerung von 195 Mikrosekunden hinzugefügt). Dieser Code funktioniert gut mit dem Klavier und einigen anderen Instrumenten.

Ich hoffe, dass dieser Code und dieses Tutorial bei Ihrem Projekt im Zusammenhang mit Musik hilfreich sind. Im Zweifelsfall oder Vorschlag zögern Sie nicht, einen Kommentar oder eine Nachricht zu senden.

Im kommenden Tutorial werde ich diesen Code für die Musikakkorderkennung ändern. Also bleibt gespannt.

Empfohlen: