/* Copyright (C) Paul Falstad and Iain Sharp This file is part of CircuitJS1. CircuitJS1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. CircuitJS1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CircuitJS1. If not, see <http://www.gnu.org/licenses/>. */ package com.lushprojects.circuitjs1.client; class FFT { private int size; private int bits; private double[] cosTable; private double[] sinTable; FFT(int n) { size = n; bits = (int) (Math.log(size) / Math.log(2)); cosTable = new double[size / 2]; sinTable = new double[size / 2]; double dtheta = -2 * Math.PI / size; for (int i = 0; i < cosTable.length; i++) { cosTable[i] = Math.cos(dtheta * i); sinTable[i] = Math.sin(dtheta * i); } } /* * This uses the radix-2 decimation-in-time FFT algorithm. * Based on * http://www.ee.columbia.edu/~ronw/code/MEAPsoft/doc/html/FFT_8java-source.html * Douglas L. Jones * University of Illinois at Urbana-Champaign * January 19, 1992 * http://cnx.rice.edu/content/m12016/latest/ */ void fft(double[] real, double[] imag) { int j = 0; int n2 = real.length / 2; for (int i=1; i < real.length - 1; i++) { int n1 = n2; while (j >= n1) { j -= n1; n1 /= 2; } j += n1; if (i < j) { double t1 = real[i]; real[i] = real[j]; real[j] = t1; t1 = imag[i]; imag[i] = imag[j]; imag[j] = t1; } } n2 = 1; for (int i = 0; i < bits; i++) { int n1 = n2; n2 <<= 1; int a = 0; for (j = 0; j < n1; j++) { double c = cosTable[a]; double s = sinTable[a]; a += 1 << (bits - i - 1); for (int k = j; k < real.length; k += n2) { int t = k + n1; double t1 = c * real[t] - s * imag[t]; double t2 = s * real[t] + c * imag[t]; real[k+n1] = real[k] - t1; imag[k+n1] = imag[k] - t2; real[k] += t1; imag[k] += t2; } } } } int getSize() { return size; } double magnitude(double real, double imag) { return Math.sqrt(real * real + imag * imag) / size; } }