0

I am trying to take the FFT and plot it. Problem is, my code works for small frequencies (like 50) but doesn't work for the bigger frequencies I need. What is going on with my code?! I expect to see a spike at the frequency of the sine wave I input, but the spike is at different frequencies depending on the sample spacing I use.

bins = 600
ss = 2048
freq = 44100
centerfreq = freq*bins/ss
# Number of samplepoints
N = ss
# sample spacing
T = 1 / 800.
x = np.linspace(0.0, N*T, N)
y = sin(2*np.pi*centerfreq*x)
yf = fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]), 'r')
  • 1
    What do you mean by "it doesn't work"? What were the inputs, what did you expect to see, what actually happened? – Jim Lewis Jan 25 '15 at 20:40
  • The inputs are as shown in the code I posted (bins, ss, freq); the output is a spike in the graph as a frequency unrelated to "centerfreq" in the code above. It seems when I change the value of "T" it moves the spike around. –  Jan 25 '15 at 20:44

1 Answers1

2

The code is right, you need to brush up your Fourier Theory and Nyquist Sampling Theorem and make sure the numbers make sense. The problem is with your x-axis scale. The plot function plots the first item in x with the first item in y, if x is not scaled up to your expectations, you are in for a surprise. You also see this if you plot a sinusoidal signal (sine wave) and expect 'degrees' and you get radians for instance. Its your duty to scale it up well so that it lines up to your expectation.

Refer to this SO answer https://stackoverflow.com/a/25735436/2061422.

from scipy import *
from numpy import *
from pylab import *  # imports for me to get going

bins = 600
ss = 2048
freq = 44100
centerfreq = freq*bins/ss
print centerfreq
# Number of samplepoints
N = ss
# sample spacing
T = 1. / freq   # i have decreased the spacing considerably
x = np.linspace(0.0, N*T, N)
sample_spacing = x[1] - x[0]  # but this is the real sample spacing
y = sin(2*np.pi*centerfreq*x)
yf = fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
freqs = np.fft.fftfreq(len(y), sample_spacing) # read the manual on this fella.
plt.plot(freqs[:N/2], 1.0/N * np.abs(yf[0:N/2]), 'r')
plt.grid()
plt.show()
Community
  • 1
  • 1
dopstar
  • 1,478
  • 10
  • 20