// Simple Fast Fourier Transform.
class Fft {
public static void complexToComplex(int sign, int n,
float ar[], float ai[]) {
float scale = (float)Math.sqrt(1.0f/n);
int i,j;
for (i=j=0; i<n; ++i) {
if (j>=i) {
float tempr = ar[j]*scale;
float tempi = ai[j]*scale;
ar[j] = ar*scale;
ai[j] = ai[i]*scale;
ar[i] = tempr;
ai[i] = tempi;
}
int m = n/2;
while (m>=1 && j>=m) {
j -= m;
m /= 2;
}
j += m;
}
int mmax,istep;
for (mmax=1,istep=2*mmax; mmax<n; mmax=istep,istep=2*mmax) {
float delta = (float)sign*3.141592654f/(float)mmax;
for (int m=0; m<mmax; ++m) {
float w = (float)m*delta;
float wr = (float)Math.cos(w);
float wi = (float)Math.sin(w);
for (i=m; i<n; i+=istep) {
j = i+mmax;
float tr = wr*ar[j]-wi*ai[j];
float ti = wr*ai[j]+wi*ar[j];
ar[j] = ar[i]-tr;
ai[j] = ai[i]-ti;
ar[i] += tr;
ai[i] += ti;
}
}
mmax = istep;
}
}
}
this is the algorithm I am trying to change so it accepts input from a file.
so I can set the imaginary parts array (ai) to zero?
how would I get the complex data points from the sound file?
ultiron wrote:I don't think so. In your position I would not be be changing this code at all. I would just be trying to arrange to invoke the method complexToComplex() with the correct arguments.
this is the algorithm I am trying to change so it accepts input from a file.
so I can set the imaginary parts array (ai) to zero?The sound file only contains the real parts which you will read and place in a float array. The corresponding imaginary parts are, well, zero! Just create an array floats with each value set to zeros!
how would I get the complex data points from the sound file?
ultiron wrote:Assuming each value is two bytes (that is the only reason the 'endianness' matters) then first convert each pair of bytes to a short using something like
Thanks for the help sabre. I think i'm almost there.
Ive been working at it and now I have the sound file stored in a byte array with endianness accounted for. How would I convert this data into a float array? I imagine its more difficult that a generic byte array to float array conversion?
short valueAsShort = (short)( (s[i] << 8) | (s[i+1] & 0xff));
and then to a float
float valueAsFloat = (float)valueAsShort;
Of course I have assumed big-endian signed but only you know what your actual format is.ultiron wrote:Since you don't know how to interpret the complex FFT result, one of the difficulties you will find is knowing whether or not your conversion from bytes to float is correct. The FFT does not care if you put rubbish into it; it will still transform it.
cheers for the help on the floats. I'm working on that now.
Im totally unsure on how to interpret the complex data. I was going to work it out when I got that actual FFT itself working.
If you've got any pointers on how to interpret the data and what exactly the data will represent then they would be greatly appreciated. I need all the help I can get.Forums are not a good place to learn the basics of signal processing. You need to get a book and/or tutorial and spend a lot of time reading. I assume that this is a school/college/university project so you should consult your tutor.
public float [] bytetofloat(byte [] convert){
float [] data = new float [convert.length/2];
for(int i = 0;i<convert.length;i+=2){
for(int j = 0; j <data.length;j++){
short valueAsShort = (short)( (convert[i] << 8) | (convert[i+1] & 0xff));
float valueAsFloat = (float)valueAsShort;
valueAsFloat = data[j];
}
}
return data;
}
ultiron wrote:Err .. isn't that back to front?
Hi, Sabre, was just looking for your opinion on the folowing code for converting a byte array to a float array?
valueAsFloat = data[j];
public static void bytetofloat(byte [] convert){
float [] data = new float [convert.length/2];
for(int i = 0;i<convert.length;i+=2){
short valueAsShort = (short)( (convert[i] << 8) | (convert[i+1] & 0xff));
float valueAsFloat = (float)valueAsShort;
System.out.println(valueAsFloat);
}
}
which produced float results ranging from ultiron wrote:Of course! What would be the point of creating the arrays if you couldn't?
yes your absolutely right. The nested loop was wrong as well.
which produced float results ranging frompublic static void bytetofloat(byte [] convert){ float [] data = new float [convert.length/2]; for(int i = 0;i<convert.length;i+=2){ short valueAsShort = (short)( (convert[i] << 8) | (convert[i+1] & 0xff)); float valueAsFloat = (float)valueAsShort; System.out.println(valueAsFloat); } }
-1370 to a bout 5000.
If i was to get there values into an array would this be OK to put into the FFT?