I am working with android project.I need FFT algorithm to process the android accelerometer data.Is there FFT library available in android sdk?
7 Answers
You can use this class, which is fast enough for real time audio analysis
public class FFT {
int n, m;
// Lookup tables. Only need to recompute when size of FFT changes.
double[] cos;
double[] sin;
public FFT(int n) {
this.n = n;
this.m = (int) (Math.log(n) / Math.log(2));
// Make sure n is a power of 2
if (n != (1 << m))
throw new RuntimeException("FFT length must be power of 2");
// precompute tables
cos = new double[n / 2];
sin = new double[n / 2];
for (int i = 0; i < n / 2; i++) {
cos[i] = Math.cos(-2 * Math.PI * i / n);
sin[i] = Math.sin(-2 * Math.PI * i / n);
}
}
public void fft(double[] x, double[] y) {
int i, j, k, n1, n2, a;
double c, s, t1, t2;
// Bit-reverse
j = 0;
n2 = n / 2;
for (i = 1; i < n - 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 = sin[a];
a += 1 << (m - i - 1);
for (k = j; k < n; 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;
}
}
}
}
}
Warning: this code appears to be derived from here, and has a GPLv2 license.
-
May I know which algorithm is implemented in the above code? It works very well, but I am curious to understand it at the algorithm level. Thanks – ishan Aug 16 '12 at 13:01
-
1@ishan: https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm – endolith Sep 05 '12 at 03:09
-
@ericlarch can this be used for EEG data as well? – Jonathan Oct 19 '12 at 03:52
-
@ericLarch - can it run real-time fft with window of 8192 samples? – Daniel Mošmondor Oct 19 '12 at 14:40
-
1What are x and y parameters to fft function? I understand that the input samples should go in the x array, but what's the purpose of y? – Pompair Mar 11 '13 at 16:21
-
1@Pompair looks like the y array is output table. – Damian Walczak Mar 11 '13 at 22:37
-
how to use this algorithm? – Shreyash Mahajan Jul 02 '13 at 07:39
-
This seems quite promising but still, what is the y parameter? Is it the wavetable ? – Igor Čordaš Aug 29 '13 at 14:31
-
36It's like we're having here an iconic "how not to write code" example. One-character variables, useless comments, absolutely no explanations on what is actually happening. – durilka Nov 06 '13 at 18:02
-
As a side note (my assumptions of varying guess-ness), x and y are arrays with input data (array of past x coordinares from accelerometer and an array of corresponding y ones). The arrays are changed in-place so make copies. What is the output - I don't know. My guess would be that 512 (for instance) input doubles are transformed into 256 complex (amplitude, phase) numbers. But that's a wild guess. – durilka Nov 06 '13 at 18:25
-
Where is this code from? Can I use it without a license? – kmort Feb 13 '14 at 17:36
-
@kmort Appears to be from here https://www.ee.columbia.edu/~ronw/code/MEAPsoft/doc/html/FFT_8java-source.html – sjmeverett Mar 05 '14 at 19:01
-
For those looking to use this. – J Wang Nov 04 '15 at 01:37
-
2To finally answer what the array y means: it's the imaginary part of the usually complex input to an FFT. In case of real numbered input the array y has to be filled with 0 prior to each call of fft(). And also a final note concerning licensing: This code is almost identical to the standard implementation of the Cooley/Tukey algorithm from the mid-1960s (e.g. published in "Numerical Recipies in C" as four1.c). – Hartmut Pfitzinger Feb 19 '16 at 18:06
-
See Franciso's answer below for a great explanation – Joe Pinsonault Apr 03 '18 at 20:57
-
what should I put on "N". It's given me the error FFT length must be a power of 2 – HandyPawan Jan 18 '21 at 10:57
Using the class at: https://www.ee.columbia.edu/~ronw/code/MEAPsoft/doc/html/FFT_8java-source.html
Short explanation: call fft() providing x as you amplitude data, y as all-zeros array, after the function returns your first answer will be a[0]=x[0]^2+y[0]^2.
Complete explanation: FFT is complex transform, it takes N complex numbers and produces N complex numbers. So x[0] is the real part of the first number, y[0] is the complex part. This function computes in-place, so when the function returns x and y will have the real and complex parts of the transform.
One typical usage is to calculate the power spectrum of audio. Your audio samples only have real part, you your complex part is 0. To calculate the power spectrum you add the square of the real and complex parts P[0]=x[0]^2+y[0]^2.
Also it's important to notice that the Fourier transform, when applied over real numbers, result in symmetrical result (x[0]==x[x.lenth-1]). The data at x[x.length/2] have the data from frequency f=0Hz. x[0]==x[x.length-1] has the data for a frequency equals to have the sampling rate (eg if you sampling was 44000Hz than it means f[0] refeers to 22kHz).
Full procedure:
- create array p[n] with 512 samples with zeros
- Collect 1024 audio samples, write them on x
- Set y[n]=0 for all n
- calculate fft(x,y)
- calculate p[n]+=x[n+512]^2+y[n+512]^2 for all n=0 to 512
- to go 2 to take another batch (after 50 batches go to next step)
- plot p
- go to 1
Than adjust the fixed number for your taste.
The number 512 defines the sampling window, I won't explain it. Just avoid reducing it too much.
The number 1024 must be always the double of the last number.
The number 50 defines you update rate. If your sampling rate is 44000 samples per second you update rate will be: R=44000/1024/50 = 0.85 seconds.

- 376
- 3
- 14
kissfft is a decent enough library that compiles on android. It has a more versatile license than FFTW (even though FFTW is admittedly better).
You can find an android binding for kissfft in libgdx https://github.com/libgdx/libgdx/blob/0.9.9/extensions/gdx-audio/src/com/badlogic/gdx/audio/analysis/KissFFT.java
Or if you would like a pure Java based solution try jTransforms https://sites.google.com/site/piotrwendykier/software/jtransforms

- 22,661
- 8
- 53
- 51
Use this class (the one that EricLarch's answer is derived from).
Usage Notes
This function replaces your inputs arrays with the FFT output.
Input
- N = the number of data points (the size of your input array, must be a power of 2)
- X = the real part of your data to be transformed
- Y = the imaginary part of the data to be transformed
i.e. if your input is (1+8i, 2+3j, 7-i, -10-3i)
- N = 4
- X = (1, 2, 7, -10)
- Y = (8, 3, -1, -3)
Output
- X = the real part of the FFT output
- Y = the imaginary part of the FFT output
To get your classic FFT graph, you will want to calculate the magnitude of the real and imaginary parts.
Something like:
public double[] fftCalculator(double[] re, double[] im) {
if (re.length != im.length) return null;
FFT fft = new FFT(re.length);
fft.fft(re, im);
double[] fftMag = new double[re.length];
for (int i = 0; i < re.length; i++) {
fftMag[i] = Math.pow(re[i], 2) + Math.pow(im[i], 2);
}
return fftMag;
}
Also see this StackOverflow answer for how to get frequencies if your original input was magnitude vs. time.
-
Can you please help me on it...How will I implement it on my project? – Ravindra Kushwaha Nov 20 '19 at 14:03
Yes, there is the JTransforms
that is maintained on github here and avaiable as a Maven plugin here.
Use with:
compile group: 'com.github.wendykierp', name: 'JTransforms', version: '3.1'
But with more recent, Gradle versions you need to use something like:
dependencies {
...
implementation 'com.github.wendykierp:JTransforms:3.1'
}

- 14,531
- 8
- 95
- 135
@J Wang Your output magnitude seems better than the answer given on the thread you have linked however that is still magnitude squared ... the magnitude of a complex number
z = a + ib
is calculated as
|z|=sqrt(a^2+b^2)
the answer in the linked thread suggests that for pure real inputs the outputs should be using a2 or a for the output because the values for
a_(i+N/2) = -a_(i),
with b_(i) = a_(i+N/2)
meaning the complex part in their table is in the second
half of the output table.
i.e the second half of the output table for an input table of reals is the conjugate of the real ...
so z = a-ia
giving a magnitude
|z|=sqrt(2a^2) = sqrt(2)a
so it is worth noting the scaling factors ... I would recommend looking all this up in a book or on wiki to be sure.

- 5,916
- 7
- 30
- 45

- 11
- 2
Unfortunately the top answer only works for Array that its size is a power of 2, which is very limiting.
I used the Jtransforms library and it works perfectly, you can compare it to the function used by Matlab.
here is my code with comments referencing how matlab transforms any signal and gets the frequency amplitudes (https://la.mathworks.com/help/matlab/ref/fft.html)
first, add the following in the build.gradle (app)
implementation 'com.github.wendykierp:JTransforms:3.1'
and here it is the code for for transforming a simple sine wave, works like a charm
double Fs = 8000;
double T = 1/Fs;
int L = 1600;
double freq = 338;
double sinValue_re_im[] = new double[L*2]; // because FFT takes an array where its positions alternate between real and imaginary
for( int i = 0; i < L; i++)
{
sinValue_re_im[2*i] = Math.sin( 2*Math.PI*freq*(i * T) ); // real part
sinValue_re_im[2*i+1] = 0; //imaginary part
}
// matlab
// tf = fft(y1);
DoubleFFT_1D fft = new DoubleFFT_1D(L);
fft.complexForward(sinValue_re_im);
double[] tf = sinValue_re_im.clone();
// matlab
// P2 = abs(tf/L);
double[] P2 = new double[L];
for(int i=0; i<L; i++){
double re = tf[2*i]/L;
double im = tf[2*i+1]/L;
P2[i] = sqrt(re*re+im*im);
}
// P1 = P2(1:L/2+1);
double[] P1 = new double[L/2]; // single-sided: the second half of P2 has the same values as the first half
System.arraycopy(P2, 0, P1, 0, L/2);
// P1(2:end-1) = 2*P1(2:end-1);
System.arraycopy(P1, 1, P1, 1, L/2-2);
for(int i=1; i<P1.length-1; i++){
P1[i] = 2*P1[i];
}
// f = Fs*(0:(L/2))/L;
double[] f = new double[L/2 + 1];
for(int i=0; i<L/2+1;i++){
f[i] = Fs*((double) i)/L;
}

- 103
- 3