FFT does not use a window function
Hi, I was taking the fact that the FFT always "jumps around" as a harsh reality of life, but I've just realized it's doing that only because we are not windowing the data. Can we please add a window function to the FFT so that it stabilizes and one can actually read and compare it?
I've tested the triangle window and it retains too much of the original jiggling, cosine window looks pretty good as does Hann window.
Cosine window patch:
diff --git a/src/com/lushprojects/circuitjs1/client/FFT.java b/src/com/lushprojects/circuitjs1/client/FFT>
index e9243a3..84aae03 100644
--- a/src/com/lushprojects/circuitjs1/client/FFT.java
+++ b/src/com/lushprojects/circuitjs1/client/FFT.java
@@ -24,6 +24,7 @@ class FFT {
private int bits;
private double[] cosTable;
private double[] sinTable;
+ private double[] winTable;
FFT(int n) {
size = n;
@@ -35,6 +36,15 @@ class FFT {
cosTable[i] = Math.cos(dtheta * i);
sinTable[i] = Math.sin(dtheta * i);
}
+
+ /* Scale the sine window up for unity gain. */
+ double gainCompensation = 1.5707963267961471;
+
+ winTable = new double[size];
+ for (int i = 0; i < winTable.length; i++) {
+ double weight = Math.sin(i * Math.PI / winTable.length);
+ winTable[i] = weight * gainCompensation;
+ }
}
/*
@@ -47,6 +57,11 @@ class FFT {
* http://cnx.rice.edu/content/m12016/latest/
*/
void fft(double[] real, double[] imag) {
+ for (int i = 0; i < real.length; i++) {
+ real[i] *= winTable[i];
+ imag[i] *= winTable[i];
+ }
+
int j = 0;
int n2 = real.length / 2;
for (int i=1; i < real.length - 1; i++) {
Although it might be interesting to add window function selection to scope settings. Let me know what you think. I'll draft an actual pull request then, @pfalstad.
Interesting, but I guess amplitude should be corrected after windowing see : https://community.sw.siemens.com/s/article/window-correction-factors
Yeah, you are obviously right. :sweat_smile: I guess multiplying taps with reciprocal of the average original tap gain should do the trick.
Love this, thanks! I don't need a pull request.