blob: 09337f127104b5908cf115e05d5ca8a018281cd1 [file] [log] [blame]
/*
* 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 com.android.cts.verifier.audio.wavelib;
public class DspFftServer {
private int mN = 0;
private int mOrder = 0;
DspBufferDouble mCos;
DspBufferDouble mSin;
public boolean isInitialized = false;
public DspFftServer(int size) {
init(size);
}
public boolean init(int size) {
boolean status = false;
mN=size;
mOrder = (int) (Math.log(mN) / Math.log(2));
if (mN == (1 << mOrder)) {
mCos = new DspBufferDouble(mN / 2);
mSin = new DspBufferDouble(mN / 2);
for (int i = 0; i < mN / 2; i++) {
mCos.mData[i] = Math.cos(-2 * Math.PI * i / mN);
mSin.mData[i] = Math.sin(-2 * Math.PI * i / mN);
}
status = true;
} else {
mN = 0;
throw new RuntimeException("FFT must be power of 2");
}
isInitialized = status;
return status;
}
public void fft(DspBufferComplex r, int sign) {
int ii, jj, kk, n1, n2, aa;
double cc, ss, t1, t2;
// Bit-reverse
jj = 0;
n2 = mN / 2;
for (ii = 1; ii < mN - 1; ii++) {
n1 = n2;
while (jj >= n1) {
jj = jj - n1;
n1 = n1 / 2;
}
jj = jj + n1;
if (ii < jj) {
t1 = r.mReal[ii];
r.mReal[ii] = r.mReal[jj];
r.mReal[jj] = t1;
t1 = r.mImag[ii];
r.mImag[ii] = r.mImag[jj];
r.mImag[jj] = t1;
}
}
// FFT
n1 = 0;
n2 = 1;
for (ii = 0; ii < mOrder; ii++) {
n1 = n2;
n2 = n2 + n2;
aa = 0;
for (jj = 0; jj < n1; jj++) {
cc = mCos.mData[aa];
ss = sign * mSin.mData[aa];
aa += 1 << (mOrder - ii - 1);
for (kk = jj; kk < mN; kk = kk + n2) {
t1 = cc * r.mReal[kk + n1] - ss * r.mImag[kk + n1];
t2 = ss * r.mReal[kk + n1] + cc * r.mImag[kk + n1];
r.mReal[kk + n1] = r.mReal[kk] - t1;
r.mImag[kk + n1] = r.mImag[kk] - t2;
r.mReal[kk] = r.mReal[kk] + t1;
r.mImag[kk] = r.mImag[kk] + t2;
}
}
}
}
}