/*
* Copyright (C) 2011 in-somnia
*
* This file is part of JAAD.
*
* JAAD is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* JAAD 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 Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.jaad.aac.gain;
//complex FFT of length 128/16, inplace
class FFT {
private static final float[][] FFT_TABLE_128 = {
{1.0f, -0.0f},
{0.99879545f, -0.049067676f},
{0.9951847f, -0.09801714f},
{0.9891765f, -0.14673047f},
{0.98078525f, -0.19509032f},
{0.97003126f, -0.24298018f},
{0.95694035f, -0.29028466f},
{0.94154406f, -0.33688986f},
{0.9238795f, -0.38268343f},
{0.9039893f, -0.42755508f},
{0.8819213f, -0.47139674f},
{0.8577286f, -0.51410276f},
{0.8314696f, -0.55557024f},
{0.8032075f, -0.5956993f},
{0.77301043f, -0.6343933f},
{0.7409511f, -0.671559f},
{0.70710677f, -0.70710677f},
{0.671559f, -0.7409511f},
{0.6343933f, -0.77301043f},
{0.5956993f, -0.8032075f},
{0.55557024f, -0.8314696f},
{0.51410276f, -0.8577286f},
{0.47139674f, -0.8819213f},
{0.42755508f, -0.9039893f},
{0.38268343f, -0.9238795f},
{0.33688986f, -0.94154406f},
{0.29028466f, -0.95694035f},
{0.24298018f, -0.97003126f},
{0.19509032f, -0.98078525f},
{0.14673047f, -0.9891765f},
{0.09801714f, -0.9951847f},
{0.049067676f, -0.99879545f},
{6.123234E-17f, -1.0f},
{-0.049067676f, -0.99879545f},
{-0.09801714f, -0.9951847f},
{-0.14673047f, -0.9891765f},
{-0.19509032f, -0.98078525f},
{-0.24298018f, -0.97003126f},
{-0.29028466f, -0.95694035f},
{-0.33688986f, -0.94154406f},
{-0.38268343f, -0.9238795f},
{-0.42755508f, -0.9039893f},
{-0.47139674f, -0.8819213f},
{-0.51410276f, -0.8577286f},
{-0.55557024f, -0.8314696f},
{-0.5956993f, -0.8032075f},
{-0.6343933f, -0.77301043f},
{-0.671559f, -0.7409511f},
{-0.70710677f, -0.70710677f},
{-0.7409511f, -0.671559f},
{-0.77301043f, -0.6343933f},
{-0.8032075f, -0.5956993f},
{-0.8314696f, -0.55557024f},
{-0.8577286f, -0.51410276f},
{-0.8819213f, -0.47139674f},
{-0.9039893f, -0.42755508f},
{-0.9238795f, -0.38268343f},
{-0.94154406f, -0.33688986f},
{-0.95694035f, -0.29028466f},
{-0.97003126f, -0.24298018f},
{-0.98078525f, -0.19509032f},
{-0.9891765f, -0.14673047f},
{-0.9951847f, -0.09801714f},
{-0.99879545f, -0.049067676f}
};
private static final float[][] FFT_TABLE_16 = {
{1.0f, -0.0f},
{0.9238795f, -0.38268343f},
{0.70710677f, -0.70710677f},
{0.38268343f, -0.9238795f},
{6.123234E-17f, -1.0f},
{-0.38268343f, -0.9238795f},
{-0.70710677f, -0.70710677f},
{-0.9238795f, -0.38268343f}
};
static void process(float[][] in, int n) {
final int ln = (int) Math.round(Math.log(n)/Math.log(2));
final float[][] table = (n==128) ? FFT_TABLE_128 : FFT_TABLE_16;
//bit-reversal
final float[][] rev = new float[n][2];
int i, ii = 0;
for(i = 0; i<n; i++) {
rev[i][0] = in[ii][0];
rev[i][1] = in[ii][1];
int k = n>>1;
while(ii>=k&&k>0) {
ii -= k;
k >>= 1;
}
ii += k;
}
for(i = 0; i<n; i++) {
in[i][0] = rev[i][0];
in[i][1] = rev[i][1];
}
//calculation
int blocks = n/2;
int size = 2;
int j, k, l, k0, k1, size2;
float[] a = new float[2];
for(i = 0; i<ln; i++) {
size2 = size/2;
k0 = 0;
k1 = size2;
for(j = 0; j<blocks; ++j) {
l = 0;
for(k = 0; k<size2; ++k) {
a[0] = in[k1][0]*table[l][0]-in[k1][1]*table[l][1];
a[1] = in[k1][0]*table[l][1]+in[k1][1]*table[l][0];
in[k1][0] = in[k0][0]-a[0];
in[k1][1] = in[k0][1]-a[1];
in[k0][0] += a[0];
in[k0][1] += a[1];
l += blocks;
k0++;
k1++;
}
k0 += size2;
k1 += size2;
}
blocks = blocks/2;
size = size*2;
}
}
}