2008-09-17 11 views
10

Ich muss die Häufigkeit einer Probe finden, gespeichert (in Vb) als Array von Byte. Probe ist eine Sinuswelle, bekannte Frequenz, so kann ich überprüfen), aber die Zahlen sind ein bisschen seltsam, und meine Mathe-Foo ist schwach. Vollständiger Wertebereich 0-255. 99% der Zahlen liegen im Bereich von 235 bis 245, aber es gibt einige Ausreißer bis zu 0 und 1, und bis zu 255 in den restlichen 1%. Wie normalisiere ich dies, um Ausreißer zu entfernen, (Berechnung des Intervalls 235-245, da es sich mit verschiedenen Samples ändern kann), und wie berechne ich dann Nulldurchgänge, um die Häufigkeit zu erhalten? Entschuldigung, wenn diese Beschreibung Müll ist!Mathematische Analyse einer Klangprobe (als ein Array von Zahlen)

+0

nicht Müll. eigentlich eine gute Frage. – Purfideas

+0

Sie möchten vielleicht den Titel zu "als ein Array von Zahlen" ändern –

Antwort

6

Die FFT ist wahrscheinlich die beste Antwort, aber wenn Sie es wirklich durch Ihre Methode tun wollen, versuchen Sie dies:

zu normalisieren, wird zuerst ein Histogramm machen zu zählen, wie viele occurrances jeden Wert von 0 bis 255 werfen Dann X Prozent der Werte von jedem Ende mit etwas wie:.

for (i=lower=0;i< N*(X/100); lower++) 
    i+=count[lower]; 
//repeat in other direction for upper 

Jetzt mit

A[i] = 255*(A[i]-lower)/(upper-lower)-128 

wegwerfen Ergebnisse außerhalb des -128..127 Bereich normalisieren.

Jetzt können Sie Nulldurchgänge zählen. Um sicherzustellen, dass Sie sich nicht durch Lärm täuschen lassen, sollten Sie den Hang über die letzten Punkte hinweg verfolgen und nur dann die Übergänge zählen, wenn die durchschnittliche Steigung richtig ist.

3

Verwendung der Fourier-Transformation, ist es viel mehr Lärm unempfindlich als Zählen Nulldurchgänge

Edit: @WaveyDavey

fand ich eine F # -Bibliothek eine FFT zu tun: From here

Wie sich heraus, die beste kostenlose Implementierung, die ich für F # Benutzer bisher gefunden habe, ist immer noch die fantastische FFTW-Bibliothek. Ihre Site verfügt über eine vorkompilierte Windows DLL . Ich habe geschrieben minimale Bindungen, die thread-sicheren Zugriff auf FFTW von F #, mit Guru und einfachen Schnittstellen ermöglichen. Leistung ist ausgezeichnet, 32-Bit Windows XP Pro ist nur bis zu 35% langsamer als 64-Bit-Linux.

Jetzt bin ich sicher, dass Sie F # lib von VB.net nennen kann, C# usw., die

+0

Any Zeiger für noob DFT/FFT in VB von Array von Byte zu tun? –

+0

Wenn die Dokumente nicht klar sind, würde ich einfach eine Frage mit dem Tag .net, "wie man F # lib von VB anrufen?" – Purfideas

5

Die Standardmethode in ihre docs sein sollte dieses Problem in Angriff ist ein Block von Daten zu betrachten, hoffentlich mindestens zweimal die tatsächliche Frequenz (mehr Daten nehmen ist nicht schlecht, also ist es gut, ein bisschen zu überschätzen), dann nehmen Sie die FFT und erraten, dass die Frequenz der größten Zahl im resultierenden FFT-Spektrum entspricht.

Übrigens, sehr ähnliche Probleme wurden hier schon einmal gestellt - Sie könnten auch nach diesen Antworten suchen.

0

Ich googelte für "grundlegende fft". Visual Basic FFT Ihre Frage schreit FFT, aber seien Sie vorsichtig, mit FFT ohne Verständnis auch nur ein wenig über DSP kann Ergebnisse führen, die Sie nicht verstehen oder nicht wissen, woher sie kommen.

1

Wenn ich gut von Ihrer Beschreibung verstanden habe, was Sie haben, ist ein Signal, das eine Kombination aus einem Sinus plus eine Konstante plus einige zufällige Störungen ist. Say, wie

wo N [n] ist das "Glitch" -Geräusch, das Sie loswerden wollen.

Wenn die Glitches eine Stichprobe lang sind, können Sie sie mit einem Medianfilter entfernen, der größer als die Glitchlänge sein muss. Auf beiden Seiten der Panne. Glitches der Länge 1, bedeutet, dass Sie mit einem Median von 3 Proben der Länge genug haben werden.

y[n] = median3(x[n]) 

Der Median berechnet so: Nehmen Sie die Proben von x Sie filtern möchten (x [n-1], x [n], x [n + 1]), sortieren, und die Ausgabe ist der mittlere.

Nun, da das Rauschsignal entfernt ist, loswerden das konstante Signal. Ich verstehe, dass der Puffer eine begrenzte und bekannte Länge hat, so dass Sie einfach den Mittelwert des gesamten Puffers berechnen können. Subtrahieren Sie es.

Jetzt haben Sie Ihr einzelnes Sinussignal. Sie können nun die Grundfrequenz berechnen, indem Sie Nulldurchgänge zählen. Zählen Sie die Anzahl der Proben über 0, in denen die frühere Probe unter 0 lag. Die Periode ist die Gesamtmenge der Proben Ihres Puffers dividiert durch diese und die Häufigkeit ist die Gegenseite (1/x) der Periode.

1

Obwohl ich mit der Mehrheit gehen und sagen würde, dass es scheint, was Sie wollen, ist eine FFT-Lösung (FFT-Algorithmus ist ziemlich schnell), wenn FFT ist nicht die Antwort aus welchem ​​Grund auch immer möchten Sie versuchen, eine Sinuskurve anzupassen zu den Daten mit einem passenden Programm und Ablesen der angepassten Frequenz.

Fityk verwenden, können Sie die Daten laden, und passen zu a*sin(b*x-c) wo 2*pi/b wird die Frequenz nach der Montage geben.

Fityk kann von einer GUI aus über eine Befehlszeile für das Skripting verwendet werden und verfügt über eine C++ - API, die direkt in Ihre Programme integriert werden kann.

Verwandte Themen