Reply by "cecco.milani" November 2, 20102010-11-02
Hi EveryBody,

I assumed my challenge was simple, but unfortunately it wasn't so simple!!! :-(

I just want to have a simple GuitarTuner made on my own.

I'm not very smart in math so I decided to started from here: http://it.wikipedia.org/wiki/Trasformata_di_Fourier_veloce

I made this simple app which gets an audio sample of the guitar's "A" string, then reads all bytes (except the header) from the wav file. After getting the byte Array, it performs an FFT and finally returns an array of complex transformed values and a complete xml file which includes all data just for importing it in SQL and making some roughly analysis...

I can't figure it out!!

Really I don't know where i'm wrong? the FFT algorithm?? or even before when converting byte array to complex?? I tried to perform an IFFT and i didn't get my original bytes array!! Arghhh!!!!

Here is some of the code so it's possible that some one could help to understand where i'm wrong...

Many thanks.

Cecco

the initial array, please note: SamplesArray is a Byte[8192]...

Complex[] spectro = new Complex[SamplesArray.Length];
for (int i = 0; i < SamplesArray.Length; i++)
{
Double data = (short)SamplesArray[i] / 32768.0;
spectro[i] = data;
}

if (FFT.isPowerOf2(spectro.Length))
{
spectro = FFT.performFFT(spectro, spectro.Length);
}

double tmp = 0.0;
double FundamentalFrequency = 0.0;
for (int i = 1; i < spectro.Length; i++)
{
if (tmp < spectro[i].Magnitude)
{
tmp = spectro[i].Magnitude;
FundamentalFrequency = (double)(i) * (double)22050/ (double)spectro.Length;
}
}

the FFT static class...

public static class FFT
{
private static int MAX = 0;

private static int log2(int N)
{
int retVal = 0;
while (N > 0)
{
N >>= 1;
retVal++;
}
return retVal - 1;
}

public static Boolean isPowerOf2(int N)
{
Boolean retVal = false;

if (N > 0 && (N & (N - 1)) == 0)
{
retVal = true;
}

return retVal;
}

private static int reverse(int N, int n)
{
int retVal = 0;
int K = log2(N);

for (int i = 1; i <= K; i++)
{
int x = n & (1 << (K - i));
if (x > 0)
{
retVal |= 1 << (i - 1);
}
}

return retVal;
}

private static Complex[] order(Complex[] vettore, int N)
{
Complex[] retVal = new Complex[MAX];
for (int i = 0; i < N; i++)
{
retVal[i] = vettore[reverse(N, i)];
}
return retVal;
}

private static Complex w(int N)
{
double myReal = 1.0 * Math.Cos(2 * Math.PI / N);
double myImag = 1.0 * Math.Sin(2 * Math.PI / N);

Complex retval = new Complex(myReal, myImag);

return retval;
}

private static Complex[] transform(Complex[] vettore, int N)
{
Complex[] retVal = order(vettore, N);
Complex[] tmp = new Complex[MAX];
int n = 1;
for (int j = 0; j < log2(N); j++)
{
for (int i = 0; i < N; i++)
{
if ((i & n) == 0)
{
tmp[i] = retVal[i];
retVal[i] = retVal[i] +
Complex.Pow(w(N), -i % n) * retVal[i + n];
}
else
{
retVal[i] = tmp[i - 1] -
Complex.Pow(w(N), -i % n) * retVal[i];
}
}
n *= 2;
}

return retVal;
}

public static Complex[] performFFT(Complex[] vettore, int N, double d)
{
MAX = N;
Complex[] retVal = transform(vettore, N);
for (int i = 0; i < N; i++)
{
retVal[i] *= d;
}

return retVal;
}

public static Complex[] performFFT(Complex[] vettore, int N)
{
MAX = N;
Complex[] vector = transform(vettore, N);

return vector;
}
}