3

I'm using the Exocortex.DSP library for C# and it's not giving me the output I expect. I'm not really sure why. The audio file I'm using in this example is a pure 800Hz tone in a 16 bit unsigned .wav file. In Audacity I can see that it's just a single sine wave. I take in the file (using NAudio) as a byte[] then convert it using BitConverter.Single. After running Fourier.FFT on the array, I'm expecting to see significant data at samples[800] and zeroes everywhere else, but that's nothing like the data I'm getting. Here's the code...

public static void Main(string[] args)
    {
        var waveChannel = new WaveChannel32(new WaveFileReader("../../Files/800Hz.wav"));
        var buffer = new byte[4096 * 4];
        waveChannel.Read(buffer, 0, 4096 * 4);
        var samples = new ComplexF[4096];

        for (int i = 0; i < 4096; i++)
        {
            samples[i].Re = BitConverter.ToSingle(buffer, i * 4);
        }
        Fourier.FFT(samples, FourierDirection.Forward);
        for (int i = 790; i < 810; i++)
            Console.WriteLine(i + ": " + samples[i]);
    }

...which gives me the following output...

790: ( -0.4223004, -0.5940632i )
791: ( -0.4242424, -0.6004524i )
792: ( -0.4241259, -0.591617i )
793: ( -0.4438736, -0.5921871i )
794: ( -0.4386246, -0.5902517i )
795: ( -0.4222358, -0.6125283i )
796: ( -0.424219, -0.586903i )
797: ( -0.4283331, -0.6008587i )
798: ( -0.4152279, -0.5989774i )
799: ( -0.4329002, -0.5994851i )
800: ( -0.4230377, -0.5904933i )
801: ( -0.4128067, -0.5878658i )
802: ( -0.4171145, -0.5898319i )
803: ( -0.4254847, -0.572481i )
804: ( -0.4199851, -0.5827408i )
805: ( -0.4186496, -0.5890546i )
806: ( -0.4181305, -0.6026474i )
807: ( -0.4402256, -0.5738652i )
808: ( -0.4149643, -0.589726i )
809: ( -0.4256677, -0.599369i )

I also tried computing the magnitude of each complex number to see if that would give me something more significant, but still got similar results. I'm not really sure if I'm missing something in the code or just not understanding the results. Help please?

ellington
  • 33
  • 3

1 Answers1

4

The 800 Hz component can't be found at signal[800]

The N complex samples of the FFT result have the frequency range

 0 Hz .. Ns/2, with Ns = sampling frequency of your time signal

With a sampling frequency of 44.1 kHz the first FFT sample is at 0 Hz (DC), the last FFT sample is at 22.05 KHz (Nyquist frequency.)

If this is a 1024 point FFT, you'll get 512 complex samples. so the distance between two FFT samples is 22050/512 == 43 Hz, so your 800Hz Line is about the 18th sample.


Edit

Why are these other components not equal to 0.0?

The Fourier Transform assumes cyclic input. If your input is not cyclic you have to apply a window to make your input finite (and fit in a single cycle.)

If you don't think about windowing you automatically apply a rectangular window: Your signal starts "suddenly" at the beginning of the FFT and ends "suddenly" at the end of the FFT. This makes a rectangular window.

Now, the FFT result happens to be the convolution of the Fourier-Transform of your input signal (a single peak) and the Fourier-Transform of this rectangular window (a sinc == sin(x)/x function).

So, what you see as the result of the FFT of a single sine component is in fact the Fourier transform of a rectangular window, a sinc function, which is zero at few points only.

DrKoch
  • 9,556
  • 2
  • 34
  • 43
  • Ok, so I wasn't considering the distance between each index in the resulting array. When I run this again and look at magnitude, I get a huge spike at index 37. I'm guessing this result is expressing 37 * 22050/1024 ≈ 800, which is the frequency I'm expecting. Is it normal to be getting more of a spike and not just plain zeroes everywhere except at the specific frequency from the audio sample? – ellington Apr 04 '15 at 16:54
  • @ellington: Yes, because your input has a small amount of noise, which translates to a small power level at all frequencies. (Even if you compute the samples without any sensor that could introduce noise, you'll still have quantization noise) – Ben Voigt Apr 04 '15 at 16:59