80 lines
2.1 KiB
C
80 lines
2.1 KiB
C
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <complex.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
complex float* fft(complex float* p, uint32_t N) {
|
|
complex float w = cexpf(-2 * I * M_PI / N);
|
|
|
|
if (N == 1)
|
|
return p;
|
|
|
|
complex float* pe = (complex float*)malloc(sizeof(complex float) * (N / 2));
|
|
complex float* po = (complex float*)malloc(sizeof(complex float) * (N / 2));
|
|
for (int i = 0; i < N - 1; i += 2) {
|
|
pe[i / 2] = p[i];
|
|
po[i / 2] = p[i + 1];
|
|
}
|
|
|
|
complex float* xe = fft(pe, N / 2);
|
|
complex float* xo = fft(po, N / 2);
|
|
|
|
complex float* ps = (complex float*)malloc(sizeof(complex float) * N);
|
|
|
|
for (int i = 0; i < N / 2; i++) {
|
|
ps[i] = xe[i] + cpowf(w, (complex float)i) * xo[i];
|
|
ps[i + N / 2] = xe[i] - cpowf(w, (complex float)i) * xo[i];
|
|
}
|
|
|
|
return ps;
|
|
}
|
|
|
|
int main() {
|
|
FILE *f = fopen("signal.csv","r");
|
|
if (!f) { perror("signal.csv"); return 1; }
|
|
|
|
double t, a;
|
|
int capacity = 1024, n = 0;
|
|
complex float *samples = malloc(sizeof(complex float) * capacity);
|
|
|
|
while (fscanf(f, "%lf;%lf", &t, &a) == 2) {
|
|
if (n >= capacity) {
|
|
capacity *= 2;
|
|
samples = realloc(samples, sizeof(complex float)*capacity);
|
|
}
|
|
samples[n++] = a;
|
|
}
|
|
fclose(f);
|
|
|
|
int fsize = 1 << (int)floorf(log2f((float)n));
|
|
|
|
complex float* cwav_data = (complex float*)malloc(sizeof(complex float) * fsize);
|
|
for (int i = 0; i < fsize; i++)
|
|
cwav_data[i] = samples[i];
|
|
|
|
complex float* ft = fft(cwav_data, fsize);
|
|
|
|
double Fe = 400.0;
|
|
|
|
FILE *gnuplot = popen("gnuplot -persistent", "w");
|
|
fprintf(gnuplot, "set title 'fft'\n");
|
|
fprintf(gnuplot, "set logscale x\n");
|
|
fprintf(gnuplot, "set logscale y\n");
|
|
fprintf(gnuplot, "plot '-' with linespoints title 'fft'\n");
|
|
|
|
for (int i = 0; i < fsize/2; i++) {
|
|
double freq = (double)i * Fe / fsize;
|
|
fprintf(gnuplot, "%f %f\n", freq ,cabsf(ft[i]));
|
|
}
|
|
fprintf(gnuplot, "e\n");
|
|
pclose(gnuplot);
|
|
|
|
free(samples);
|
|
free(cwav_data);
|
|
free(ft);
|
|
|
|
return 0;
|
|
}
|
|
|