# FFT Frequency-Spectrum has noise

I am plotting a Frequency-Amplitude Graph using openGL for the graph and Rosetta FFT implementation for the FFT calculations, I generated a 2 waveform, applied Hanning window, applied FFT and calculated the magnitude, when I plotted the graph I noticed the graph isn't smooth like it's suppose to be, like I generate the waves and nothing else so why does it come up like that.

Here is the output I'm getting:

My full code:

fft.h:

#define _USE_MATH_DEFINES
#include <complex>
#include <valarray>

typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;

void fft(CArray& x)
{
const size_t N = x.size();
if (N <= 1) return;

// divide
CArray even = x[std::slice(0, N / 2, 2)];
CArray  odd = x[std::slice(1, N / 2, 2)];

// conquer
fft(even);
fft(odd);

// combine
for (size_t k = 0; k < N / 2; ++k)
{
Complex t = std::polar(1.0, -2 * M_PI * k / N) * odd[k];
x[k] = even[k] + t;
x[k + N / 2] = even[k] - t;
}
}


main.cpp:

#define _USE_MATH_DEFINES
#include <GL/glut.h>

#include <stdio.h>
#include <iostream>
#include <cmath>
#include "fft.h"

using namespace std;

const int N = 1000;
Complex in[N];
double test[N];
double t[N];//time vector
float frequencies[N];
double mag[N];

void drawText(float x, float y, char *string) {
int len, i;
glRasterPos2f(x, y);
len = (int)strlen(string);
for (i = 0; i < len; i++)
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, string[i]);
}
}

void display()
{
glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH); glLineWidth(2);

glMatrixMode(GL_PROJECTION);
glOrtho(-6, 6, -6, 6, -1, 1);

glMatrixMode(GL_MODELVIEW);

glColor4f(0.4, 1.0, 0.6, 1);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < N; i++)
{
glVertex2f(t[i] - 5, test[i]);
}
glEnd();
glutSwapBuffers();
}

void displayFreqSpec()
{
char str[] = "hello";
glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH); glLineWidth(2);

glMatrixMode(GL_PROJECTION);
glOrtho(0, 6, 0, 6, -1, 1);
glScalef(0.1, 0.03, 0.1);
glRotatef(0, 0, 0, 10);
glMatrixMode(GL_MODELVIEW);

glColor4f(0.4, 1.0, 0.6, 1);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < N / 2; i++)
{
glVertex2f(frequencies[i] + 5, mag[i]);
}
glEnd();
glutSwapBuffers();
}

int main(int argc, char** argv)
{
int i;
double y;
const double Fs = 100;//How many time points are needed i,e., Sampling Frequency
const double  T = 1 / Fs;//# At what intervals time points are sampled
const double f = 4;//frequency

for (int i = 0; i < N; i++)
{
t[i] = i * T;
in[i] = { (0.7 * cos(2 * M_PI * 25 * t[i])), (0.7 * sin(2 * M_PI * f * t[i])) };// generate (complex) sine waveform
double multiplier = 0.5 * (1 - cos(2 * M_PI * i / (N)));//Hanning Window
in[i] = multiplier * in[i];
test[i] = in[i].real() + in[i].imag();
}
CArray data(in, N);

printf("\n");
printf("  Input Data(only the imag value):\n");
printf("\n");

for (i = 0; i < N; i++)
{
printf("%4d  %12f\n", i, in[i].real());
}

fft(data);

/*
printf("output Data from FFT implementation:\n");

for (int i = 0; i < N; ++i)
{
std::cout << data[i] << std::endl;
}

*/

printf("\n");
printf("log magnitude of frequency domain components :\n");
for (i = 0; i < N; i++)
{
mag[i] = std::abs(data[i]);
std::cout << mag[i] << endl;
}

//might need this part to calculate spectrogram
int tpCount = N;
int values[1000];

for (int i = 0; i < 1000; i++)
values[i] = i;
float timePeriod = tpCount / Fs;

//printf("\n");

for (int i = 0; i < 1000; i++)
{
frequencies[i] = values[i] / timePeriod;
}

// GUI Stuff
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600, 600);

glutCreateWindow("Graph showing the waveform after hanning window");
//glutDisplayFunc(display);
glutDisplayFunc(displayFreqSpec);
glutMainLoop();
return 0;
}

• Does it work if you use a power of 2 length? It looks like you have N = 1000, try 1024. Looks like a radix 2 implementation, which only works with powers of 2. May 21, 2021 at 17:04
• that actually fixed it wow, can you provide an explanation in the answers and I'll mark it as the correct answer? @DanSzabo May 21, 2021 at 17:15