Ich benutze eine Version von "KISS FFT" von Mark Borgerding. Es akzeptiert ein Array von 16-Bit-Festkomma-Eingabewerten und erzeugt ein 32-Bit-Float-Ergebnisarray.
Ich habe festgestellt, dass bei niedrigen Eingangsamplituden viele der Float-Ergebniswerte Null sind. Wenn ich jedoch die Eingänge einfach skaliere (z. B. um den Faktor 16), sind weniger Ausgangswerte Null und daher scheint der Ausgang zu enthalten Mehr Details. (Nicht, dass es für meine Zwecke wichtig ist, aber aus Gründen der Konsistenz dividiere ich dann die resultierenden Float-Werte durch denselben Skalierungsfaktor.)
Wie auch immer, dies scheint zu funktionieren, um ein Ergebnis zu erzielen, wenn ich zuvor nur einen Puffer mit praktisch allen Nullen erhalten hätte, aber ich frage mich, ob es einen Grund gibt, warum dies möglicherweise kein gültiger Ansatz ist.
(Beachten Sie, dass dieser Ansatz bedeutet, dass die Daten viel "gröber" / granularer sind, und insbesondere das normalerweise vorhandene geringe Rauschen ist nicht vorhanden. Ich frage mich fast, ob es sinnvoll wäre, zu injizieren etwas leises Rauschen, um die Nullwerte im Eingang zu ersetzen.)
Antworten:
Dies kann ein gültiger Ansatz sein. Sie beobachten ein sehr praktisches Problem, das häufig bei der Verwendung von Festkomma-Arithmetik (dh Ganzzahl-Arithmetik) auftritt (obwohl dies auch im Gleitkomma auftreten kann). Wenn das numerische Format, das Sie zum Ausführen von Berechnungen verwenden, nicht genau genug ist, um den gesamten Wertebereich auszudrücken, der sich aus Ihren Berechnungen ergeben kann, ist eine Form der Rundung erforderlich (z. B. Abschneiden, Runden auf die nächste usw.) auf). Dies wird häufig als additiver Quantisierungsfehler zu Ihrem Signal modelliert .
Bei einigen Kombinationen von Algorithmus und Rundungsschema ist es jedoch möglich, bei einer sehr geringen Größe des Eingangssignals das zu erhalten, was Sie beobachtet haben: eine große Anzahl von Null-Ausgängen. Grundsätzlich werden die Zwischenergebnisse irgendwo in der Abfolge der Operationen klein genug, um den Schwellenwert, der zum Quantisieren auf ein Niveau ungleich Null erforderlich ist, nicht zu überschreiten. Der Wert wird dann auf Null gerundet, was sich häufig vorwärts zum Ausgang ausbreiten kann. Das Ergebnis ist, wie Sie bemerkt haben, ein Algorithmus, der viele Ausgangsnullen erzeugt.
Können Sie dies umgehen, indem Sie die Daten vergrößern? Manchmal (es gibt nur sehr wenige Techniken, die ständig funktionieren!). Wenn Ihr Eingangssignal in seiner Größe auf einen Wert unter dem Skalenendwert des numerischen Formats begrenzt ist (16-Bit-Ganzzahlen mit Vorzeichen reichen von -32768 bis +32767), können Sie das Eingangssignal skalieren, um den verfügbaren Bereich besser zu nutzen es. Dies kann dazu beitragen, die Auswirkungen eines Rundungsfehlers abzuschwächen, da die Größe eines Rundungsfehlers im Vergleich zum interessierenden Signal kleiner wird. In dem Fall, in dem alle Ihre Ausgaben intern im Algorithmus auf Nullen gerundet werden, kann dies hilfreich sein.
Wann kann dich eine solche Technik verletzen? Abhängig von der Struktur der Berechnungen des Algorithmus können Sie durch Skalieren des Eingangssignals numerischen Überläufen ausgesetzt werden. Wenn das Signal Hintergrundrauschen oder Interferenzen enthält, deren Größe größer ist als der Rundungsfehler des Algorithmus, wird die Qualität dessen, was Sie am Ausgang erhalten, normalerweise durch die Umgebung begrenzt, nicht durch Fehler, die bei der Berechnung auftreten.
quelle
Der einfachste und narrensicherste Weg, damit umzugehen, besteht darin, die Daten VOR der FFT in Gleitkomma umzuwandeln und eine Gleitkomma-FFT zu verwenden. Der einzige Nachteil dieses Ansatzes wäre, dass Sie möglicherweise mehr Prozessor und Speicher verbrauchen. Da Ihre Ausgabe ohnehin Gleitkomma ist, gibt es wahrscheinlich kaum einen praktischen Unterschied.
quelle