/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.drrickorang.loopback;


/**
 * This class computes FFT of inputting data.
 * Note: this part of code is originally from another project, so there's actually multiple copies
 * of this code. Should somehow merge these copies in the future. Also, no modification on
 * naming has been made, but naming should be changed once we merge all copies.
 */

public class FFT {
    private int       m;
    private double[]  cos;   // precomputed cosine tables for FFT
    private double[]  sin;   // precomputed sine tables for FFT
    private final int mFFTSamplingSize;


    FFT(int FFTSamplingSize) {
        mFFTSamplingSize = FFTSamplingSize;
        setUpFFT();
    }


    /** This function is only called in constructor to set up variables needed for computing FFT. */
    private void setUpFFT() {
        m = (int) (Math.log(mFFTSamplingSize) / Math.log(2));

        // Make sure n is a power of 2
        if (mFFTSamplingSize != (1 << m))
            throw new RuntimeException("FFT sampling size must be power of 2");

        // precomputed tables
        cos = new double[mFFTSamplingSize / 2];
        sin = new double[mFFTSamplingSize / 2];

        for (int i = 0; i < mFFTSamplingSize / 2; i++) {
            cos[i] = Math.cos(-2 * Math.PI * i / mFFTSamplingSize);
            sin[i] = Math.sin(-2 * Math.PI * i / mFFTSamplingSize);
        }
    }


    /**
     * Do FFT, and store the result's real part to "x", imaginary part to "y".
     */
    public void fft(double[] x, double[] y, int sign) {
        int i, j, k, n1, n2, a;
        double c, s, t1, t2;

        // Bit-reverse
        j = 0;
        n2 = mFFTSamplingSize / 2;
        for (i = 1; i < mFFTSamplingSize - 1; i++) {
            n1 = n2;
            while (j >= n1) {
                j = j - n1;
                n1 = n1 / 2;
            }
            j = j + n1;

            if (i < j) {
                t1 = x[i];
                x[i] = x[j];
                x[j] = t1;
                t1 = y[i];
                y[i] = y[j];
                y[j] = t1;
            }
        }

        // FFT
        n1 = 0;
        n2 = 1;

        for (i = 0; i < m; i++) {
            n1 = n2;
            n2 = n2 + n2;
            a = 0;

            for (j = 0; j < n1; j++) {
                c = cos[a];
                s = sign * sin[a];
                a += 1 << (m - i - 1);

                for (k = j; k < mFFTSamplingSize; k = k + n2) {
                    t1 = c * x[k + n1] - s * y[k + n1];
                    t2 = s * x[k + n1] + c * y[k + n1];
                    x[k + n1] = x[k] - t1;
                    y[k + n1] = y[k] - t2;
                    x[k] = x[k] + t1;
                    y[k] = y[k] + t2;
                }
            }
        }
    }
}
