audiojuliasignal-processingfftaudacity

Why is a tiny change in chirp frequency causing a major change in the Fast-Fourier-Tranform output?


Using Audacity, I generated and exported two very similar chirps of 1 second each. One has a frequency of 440.00Hz, and the other has a frequency of 440.01Hz.

Using Julia, I made a short script to generate a plot of the FFT:

using WAV
using FFTW
using PyPlot

data, bps = wavread("440.01hz.wav")
plot(fft(data))

The 440.01 plot looked about how I would expect, with a big spike at that frequency: Spike at around 440 However, the same procedure repeated on the exact integer 440 file yielded this result: Squiggle line A very jagged line with no spike. And zoomed out it looks like this (x-axis goes to 44100 since that was the beats-per-second of the file): Wild graph I've repeated the procedure with several more frequencies, and it seems to always produce a good (sensible?) result when the frequency is a non-integer, and a confusing result otherwise. What problem am I running into here?

Edit:

Here are the files:

440.00Hz http://www.mediafire.com/file/n6erdh3tkzslpro/440.00hz.wav/file

440.01Hz http://www.mediafire.com/file/2au05df2aelmn9o/440.01hz.wav/file

And here's a plot of both waves (almost indistinguishable) plotted with both fft's zoomed in:

enter image description here

And zoomed out:

enter image description here

The code used to generate these is the same as the one above, but with 4 plots (440 WAV, 440 FFT, 440.01 WAV, 440.01 FFT).

Edit2:

I figured out at least part of the problem. If I first pass the fourier transform of the 440.00hz wav to the absolute value function before plotting it plot(fft(data) .|> abs), I get a correct result:

enter image description here

So I know the solution to the problem now, but not why the solution works. The question still remains: what is it about integer frequencies that produces a graph with no spikes? Or, equally valid, why do fractional frequencies produce graphs with them?


Solution

  • The (real) FFT decomposes your signal into a sum of sinusoidal components.

    For each frequency you get a complex number. (ignoring the negative frequencies for now) The real part gives the cosine component, and the imaginary part gives the sine component.

    You are making a .wav file with a sine wave in it, so you only get sine components, but you're plotting the real components so they're all 0.

    Except... The FFT considers your signal to be periodic. When you use an arbitrary frequency, you don't end up with an integer number of cycles in the file, so there is a discontinuity when it wraps around from the end to the start.

    Since your signal is not a perfect sinusoid in that case, you get some energy in the cosine components.

    --

    What you're doing with this FFT is probably very far from what you want to do. If you ask a question about how to do what you're really trying to do, we might be able to help.