0
$\begingroup$

enter image description hereI have written a script to plot the frequency spectrum of a sinusoidal signal with c++. Here are the steps 1-Applying Hanning window 2-Apply FFT using fftw3 library I have three graphs: Signal, Signal when is multiplied to Hanning function, and the frequency spectrum. The frequency spectrum looks wrong. It should have a pick at 50 Hz.Any suggestion would be appreciated. Here is the code:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <fftw3.h>
#include <iostream>
#include <cmath>
#include <fstream>
using namespace std;

int main()
{
int i;
double y;
int N=50;
double Fs=1000;//sampling frequency
double  T=1/Fs;//sample time 
double f=50;//frequency
double *in;
fftw_complex *out;
double t[N];//time vector 
double ff[N];
fftw_plan plan_forward;

in = (double*) fftw_malloc(sizeof(double) * N);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);

 for (int i=0; i< N;i++)
 {
    t[i]=i*T;
    ff[i]=1/t[i];
    in[i] =0.7 *sin(2*M_PI*f*t[i]);// generate sine waveform
    double multiplier = 0.5 * (1 - cos(2*M_PI*i/(N-1)));//Hanning Window
    in[i] = multiplier * in[i];
  }

  plan_forward = fftw_plan_dft_r2c_1d ( N, in, out, FFTW_ESTIMATE );

  fftw_execute ( plan_forward );

  double v[N];

  for (int i = 0; i < N; i++)
    {

    v[i]=20*log(sqrt(out[i][0]*out[i][0]+ out[i][1]*out[i][1])/N/2);//Here I have calculated the y axis of the spectrum in dB

    }

   fstream myfile;

   myfile.open("example2.txt",fstream::out);

   myfile << "plot '-' using 1:2" << std::endl;

   for(i = 0; i < N; ++i)

    { 

      myfile << ff[i]<< " " << v[i]<< std::endl;

    }

 myfile.close();

 fftw_destroy_plan ( plan_forward );
 fftw_free ( in );
 fftw_free ( out );
 return 0;
  }

I have to add that I have plotted the graphs using gnuplot after inserting the results into example2.txt. So ff[i] vs v[i] should give me the frequency spectrum.

Here are the plots: enter image description here Frequency Spectrum and Sinusoidal time Window respectively: enter image description here

Edit: After applying the changes to frequency sampling, this is the graph I got:enter image description here Edit: The first graph is the plot for frequency spectrum vs time

$\endgroup$
  • $\begingroup$ You probably don't want to plot it on a logarithmic scale. Values very close to zero (as you have around zero frequency) will completely obliterate the actual useful signal. $\endgroup$ – Peter K. Aug 28 '15 at 18:04
  • $\begingroup$ Even when I change v[i] to v[i]=sqrt(out[i][0]*out[i][0]+ out[i][1]*out[i][1]); the result looks wrong. $\endgroup$ – Jack Aug 28 '15 at 18:07
0
$\begingroup$

You seem to be doing something odd with your frequency axis. This:

t[i]=i*T;
ff[i]=1/t[i];

should probably read:

t[i]=i*T;
ff[i]=Fs*i/N;

The frequency axis you have now is nonlinear. The FFT generally generates linearly spaced frequency samples.

$\endgroup$
  • $\begingroup$ Only Fs * i/N works..Fs * i does not render any good result. $\endgroup$ – Jack Aug 28 '15 at 18:28
  • $\begingroup$ I have added the new plot above. $\endgroup$ – Jack Aug 28 '15 at 18:33
  • $\begingroup$ Yes, thats much more like it. $\endgroup$ – Peter K. Aug 28 '15 at 18:39
  • $\begingroup$ But there is something wrong because now I try to plot time vs v[i] to get the spectrogram and the graph looks funny. I will ass it to my question above. $\endgroup$ – Jack Aug 28 '15 at 18:40
  • $\begingroup$ v[i] is a frequency-domain variable. It makes little sense to try to plot it against time. $\endgroup$ – Peter K. Aug 28 '15 at 18:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.