Ich will ein Tool programmieren, was per DMX MovingHeads in Abhängigkeit
vom aktuellen Umgebungs-Sound steuert - so eine Art moderne Lichtorgel.
Was ich bereits habe und was funktioniert sind Programm-Fragmente für:
- Soundgrabbing (liefert eine festgelegte Anzahl von Samples in einem
Array)
- DMX-Ausgabe
Zur Trennung der Spektralanteile (und deren Verteilung auf die
DMX-Kanäle) möchte ich FFT verwenden, dazu habe ich ein Beispielprogramm
mit einer entsprechenden Funktion. Leider blicke ich bei deren Nutzung
nicht ganz durch, zumal der Beispielcode nur mit einer Listenausgabe
daher kommt.
Als Übergabeparameter bekommt diese Funktion ein Array mit komplexen
Zahlen, die vorher aus meinem Array mit den Sampling-Daten erzeugt
werden (z.B. 1024 Werte). Zurück bekomme ich ein gleich großes Array
voller komplexer Zahlen ... und nun? Wie bekomme ich daraus die
spektralen Anteile? Ist so verdammt lang her ...
1
dim N,k as integer //Anzahl der Eingangs-Werte
2
dim x() as Double //Array für Eingangswerte real
3
dim c() as Complex //Array für Eingangswerte komplex
4
5
N=1023
6
7
for k = 0 to N
8
x.Append sin(k/10) + 0.5 * sin(k/3) 'Erzeugen von Beispiel-Eingangswerten mit zwei Sinus-Funktionen
9
next
10
11
for k = 0 to N
12
c.append new Complex(x(k),0) // Complex with real part = x(k) and imaginary part = 0
13
next
14
15
// Calculate FFT
16
dim C_() as Complex = fft(c)
17
18
// Extract magnitudes
19
dim m() as double
20
21
for k = 0 to N
22
m.Append C_(k).Abs
23
next
24
25
for k=0 to N //Ausgabe der Ergebnisse in eine Tabelle
Na, steht doch im Code.
"Magnitude" = Amplitude des jeweiligen Frequenzanteils.
Der Imaginärteil beinhaltet die Phasenlage (für deinen Anwendungsfall
uninteressant).
Joe F. schrieb:> Na, steht doch im Code.> "Magnitude" = Amplitude des jeweiligen Frequenzanteils.> Der Imaginärteil beinhaltet die Phasenlage (für deinen Anwendungsfall> uninteressant).
Ja, das habe ich auch schon vermutet.
Finde es nur seltsam, dass es genau so viele Frequenzanteile gibt, wie
Eingangswerte ... oder ist das dem vereinfachten bzw. digital
optimierten Algorithmus geschuldet?
Frank E. schrieb:> oder ist das dem vereinfachten bzw. digital> optimierten Algorithmus geschuldet?
Das ist das Prinzip von FFT.
Wenn du übrigens nur ein paar wenige Frequenzbänder beobachten willst,
könnte der Goertzel-Algorithmus deutliche Geschwindigkeitsvorteile
gegenüber einer FFT bringen.
Frank E. schrieb:> Finde es nur seltsam, dass es genau so viele Frequenzanteile gibt, wie> Eingangswerte ... oder ist das dem vereinfachten bzw. digital> optimierten Algorithmus geschuldet?
Eigentlich gibt es sogar doppelt so viele, das Ergebnis ist ja komplex.
Liegt aber daran, dass die FFT an sich auch komplexe Eingangsdaten hat,
die bei der real->complex-FFT aber mit 0 belegt werden.
Danke für den Hinweis auf Goertzel, habe diesen Code hier gefunden und
werde mal versuchen, ihn umzusetzen.
https://netwerkt.wordpress.com/2011/08/25/goertzel-filter/
Eine Frage hätte ich noch: An welchem Parameter müsste ich "drehen", um
die Bandbreite zu beeinflussen? Denn eigentlich will ich ja nicht eine
ganz konkrete Frequenz, sondern so Bereiche bzw. Bänder?
Hilft es da, mit der Anzahl der Samples zu spielen?
Frank E. schrieb:> Hilft es da, mit der Anzahl der Samples zu spielen?
Genau. Je weniger Samples, desto weniger Bänder und desto breiter die
Bänder.
Das hat natürlich Grenzen, da man tiefe Frequenzen nur mit genügend
Samples analysieren kann.
Dem kann man dann aber z.B. mit Downsampling begegnen.
Eine andere Möglichkeit wäre noch BiQuads zu benutzen.
Da kannst du Q recht frei wählen.
Dabei fällt natürlich nicht direkt die Amplitude raus, du müsstest für
die Bänder eine Spitzenwerterkennung mit drop-down implementieren
(ähnlich einem Level Meter eines Mischpultes).
>Frank>Finde es nur seltsam, dass es genau so viele Frequenzanteile gibt, wie
Eingangswerte ... oder ist das dem vereinfachten bzw. digital
optimierten Algorithmus geschuldet?
Es geht sogar noch etwas weiter. Die Fouriertransformation ist
bidirektional. Zeitraum <-> Frequenzraum, oder auch Ortsraum <->
Impulsraum
Eine eigene Frage?
Dieser Thread ist über 9 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.