Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Simulated waveforms shouldn't show FFTs like your figure, so something is very wrong, and probably not with the FFT, but with the input waveform. The main problem in your plot is not the ripples, but the harmonics around 1000 Hz, and the subharmonic at 500 Hz. A simulated waveform shouldn't show any of this (for example, see my plot below).</p> <p>First, you probably want to just try plotting out the raw waveform, and this will likely point to an obvious problem. Also, it seems odd to have a wave unpack to unsigned shorts, i.e. "H", and especially after this to not have a large zero-frequency component.</p> <p>I was able to get a pretty close duplicate to your FFT by applying clipping to the waveform, as was suggested by both the subharmonic and higher harmonics (and Trevor). You could be introducing clipping either in the simulation or the unpacking. Either way, I bypassed this by creating the waveforms in numpy to start with.</p> <p>Here's what the proper FFT should look like (i.e. basically perfect, except for the broadening of the peaks due to the windowing)</p> <p><a href="http://i43.tinypic.com/1rvsqx.png" rel="nofollow noreferrer">alt text http://i43.tinypic.com/1rvsqx.png</a></p> <p>Here's one from a waveform that's been clipped (and is very similar to your FFT, from the subharmonic to the precise pattern of the three higher harmonics around 1000 Hz)</p> <p><a href="http://i44.tinypic.com/mt4avd.png" rel="nofollow noreferrer">alt text http://i44.tinypic.com/mt4avd.png</a> Here's the code I used to generate these</p> <pre><code>from numpy import * from pylab import ion, plot, draw, show, xlabel, ylabel, figure sample_rate = 20000. times = arange(0, 10., 1./sample_rate) wfm0 = sin(2*pi*200.*times) wfm1 = sin(2*pi*500.*times) *(10.-times)/10. wfm = wfm0+wfm1 # int test #wfm *= 2**8 #wfm = wfm.astype(int16) #wfm = wfm.astype(float) # abs test #wfm = abs(wfm) # clip test #wfm = clip(wfm, -1.2, 1.2) fft_length = 5*2048. total_num_samps = len(times) num_fft = (total_num_samps / fft_length ) - 2 temp = zeros((num_fft,fft_length), float) for i in range(num_fft): temp[i,:] = wfm[i*fft_length:(i+1)*fft_length] pts = fft_length/2+1 data = (abs(fft.rfft(temp, fft_length)) / (pts))[:pts] x_axis = arange(pts)*sample_rate*.5/pts spec_range = pts plot(x_axis, data[2], linewidth=3) xlabel("freq (Hz)") ylabel('abs(FFT)') show() </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload