Ich versuche, einen selbstgebauten Spektrumanalysator mit 8 LED-Streifen zu erstellen.
Der Teil, mit dem ich zu kämpfen habe, ist die FFT durchzuführen und zu verstehen, wie man die Ergebnisse verwendet.
Bisher habe ich Folgendes:
%Vor% Ich habe Probleme mit der Methode pitch
. Ich weiß, dass ich FFT auf den Daten durchführen muss, die übergeben werden, aber bin wirklich nicht sicher, wie man es macht.
Sie sollten auch dies verwenden Funktion?
Aufgrund der Funktionsweise von np.fft.fft erhalten Sie bei Verwendung von 1024 Datenpunkten Werte für 512 Frequenzen (plus einen Wert von Null Hz, DC-Offset ). Wenn Sie nur 8 Frequenzen haben wollen, müssen Sie 16 Datenpunkte füttern.
Sie können möglicherweise das tun, was Sie wollen, indem Sie einen Faktor von 64 abtasten - dann wären 16 abgetastete Punkte zeitäquivalent zu 1024 ursprünglichen Punkten. Ich habe das nie erforscht, also weiß ich nicht, was das mit sich bringt oder was die Fallstricke sein könnten.
Sie werden etwas lernen müssen - Der Leitfaden für Wissenschaftler und Ingenieure zur digitalen Signalverarbeitung ist wirklich ein ausgezeichnete Ressource, zumindest war es für mich.
Beachten Sie, dass die Sample-Frequenz für eine Audio-CD-WAV-Datei 44100 Hz beträgt - ein 1024-Sample-Chunk beträgt nur 23 ms des Sounds .
scipy .io.wavfile.read erleichtert das Abrufen der Daten.
%Vor% data
ist ein 2-d-numpy-Array mit einem Kanal in Spalte Null, Daten [:, 0], und der andere in Spalte 1, Daten [:, 1]
Matplotlibs Specgramm und die psd-Funktionen können Ihnen die gewünschten Daten liefern. Eine grafische Analogie zu dem, was Sie versuchen zu tun wäre.
%Vor%Da Sie nicht plotten, verwenden Sie einfach matplolib.mlab.specgram .
%Vor%Seine Rückgabewerte ( Pxx , Häufigkeiten , t ) sind
%Vor% Pxx[1:, 0]
wären die Werte für die Frequenzen für T0, Pxx[1:, 1]
für T1, Pxx[1:, 2]
für T2, ... Dies würden Sie Ihrem Display zuführen. Sie verwenden Pxx[0, :]
nicht, weil es für 0 Hz ist.
Leistungsspektraldichte - matplotlib.mlab.psd ()
Vielleicht wäre eine andere Strategie, um zu 8 Bändern zu kommen , große Stücke zu verwenden und die Werte zu normalisieren. Dann könnten Sie die Werte in acht Segmente aufteilen und die Summe der Segmente erhalten. Ich denke, das ist gültig - vielleicht nur für die spektrale Leistungsdichte. sklearn.preprocessing.normalize
%Vor%Aber dann habe ich das alles einfach gemacht.
Ich weiß nicht über die Funktion scipy.io.wavfile.read
, die @wwii in seiner Antwort erwähnt, aber es scheint, dass sein Vorschlag der richtige Weg ist, um mit dem Signalladen umzugehen. Ich wollte jedoch nur die Fourier-Transformation kommentieren.
Was ich mir vorstelle, dass Sie mit Ihrer LED-Einrichtung machen wollen, ist, die Helligkeit der LEDs entsprechend der Stärke der Spektren in jedem der 8 Frequenzbänder zu ändern, die Sie verwenden möchten. Was ich also verstanden habe, ist, die Macht mit der Zeit irgendwie zu berechnen. Die erste Komplikation ist "Wie berechnet man die spektrale Stärke?"
Der beste Weg, dies zu tun, ist mit der numpy.fft.rfft
, die die Fourier-Transformation für Signale berechnet, die nur reelle Zahlen haben (keine komplexen Zahlen). Auf der anderen Seite ist die Funktion numpy.fft.fft
eine Allzweckfunktion, die die schnelle Fourier-Transformation für Signale mit komplexen Zahlen berechnen kann. Der konzeptionelle Unterschied besteht darin, dass numpy.fft.fft
verwendet werden kann, um Wanderwellen und ihre Ausbreitungsrichtung zu untersuchen. Dies wird beobachtet, weil die zurückgegebenen Amplituden positiv oder negativ entsprechen Frequenzen , die angeben, wie sich die Welle bewegt. numpy.fft.rfft
liefert die Amplitude für reellwertige Frequenzen, wie in numpy.fft.rfftfreq
angezeigt, was Sie brauchen.
Das letzte Problem besteht darin, geeignete Frequenzbänder zu wählen, in denen die spektrale Leistung berechnet wird. Das menschliche Ohr hat einen großen Frequenzbereich und die Breite jedes Bandes wird sehr unterschiedlich sein, wobei das tiefe Frequenzband sehr schmal und das hohe Frequenzband sehr breit ist. Beim Durchstöbern fand ich diese nette Ressource, die 7 relevante Frequenzbänder definiert
Ich würde vorschlagen, diese Bänder zu verwenden, aber den oberen Mittenbereich in 2-3 kHz und 3-4 kHz aufzuteilen. Auf diese Weise können Sie Ihr 8-LED-Setup verwenden. Ich lade eine aktualisierte Pitch-Funktion hoch, die Sie verwenden können
%Vor% Der erste Teil des Codes berechnet die fft-Frequenzen und konstruiert das Array FFT_FREQS_INDS
, das anzeigt, welchem der 8 Frequenzbänder die fft-Frequenz entspricht. Dann wird in pitch
die Stärke der Spektren in jedem der Bänder berechnet. Natürlich kann dies optimiert werden, aber ich habe versucht, den Code selbsterklärend zu machen.