linuxOS_AP06/app/lvgl_demo/flexbus/fft.c
2025-06-03 12:28:32 +08:00

102 lines
2.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*代码来源https://www.math.wustl.edu/~victor/mfmm/fourier/fft.c*/
/*华盛顿大学的教学代码*/
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//#define q 8 /* 2^q 点256 */
//#define N (1<<q) /* N点 FFT, iFFT */
typedef float real;
typedef struct
{
real Re;
real Im;
} complex;
#ifndef PI
# define PI 3.14159265358979323846264338327950288
#endif
/*为了更好说明分治思想这里采用递归实现结束条件为N<=1*/
void fft(complex *v, int n, complex *tmp)
{
if (n > 1) /* N如小于1直接返回*/
{
int k, m;
complex z, w, *vo, *ve;
ve = tmp;
vo = tmp + n / 2;
for (k = 0; k < n / 2; k++)
{
ve[k] = v[2 * k];
vo[k] = v[2 * k + 1];
}
fft(ve, n / 2, v); /* FFT 偶数序列 v[] */
fft(vo, n / 2, v); /* FFT 偶数序列 v[] */
for (m = 0; m < n / 2; m++)
{
w.Re = cos(2 * PI * m / (double)n);
w.Im = -sin(2 * PI * m / (double)n);
z.Re = w.Re * vo[m].Re - w.Im * vo[m].Im; /* Re(w*vo[m]) */
z.Im = w.Re * vo[m].Im + w.Im * vo[m].Re; /* Im(w*vo[m]) */
v[ m ].Re = ve[m].Re + z.Re;
v[ m ].Im = ve[m].Im + z.Im;
v[m + n / 2].Re = ve[m].Re - z.Re;
v[m + n / 2].Im = ve[m].Im - z.Im;
}
}
return;
}
/*为了更好说明分治思想这里采用递归实现结束条件为N<=1*/
void ifft(complex *v, int n, complex *tmp)
{
if (n > 1)
{
int k, m;
complex z, w, *vo, *ve;
ve = tmp;
vo = tmp + n / 2;
for (k = 0; k < n / 2; k++)
{
ve[k] = v[2 * k];
vo[k] = v[2 * k + 1];
}
ifft(ve, n / 2, v); /* FFT 偶数序列 v[] */
ifft(vo, n / 2, v); /* FFT 奇数序列 v[] */
for (m = 0; m < n / 2; m++)
{
w.Re = cos(2 * PI * m / (double)n);
w.Im = sin(2 * PI * m / (double)n);
z.Re = w.Re * vo[m].Re - w.Im * vo[m].Im; /* Re(w*vo[m]) */
z.Im = w.Re * vo[m].Im + w.Im * vo[m].Re; /* Im(w*vo[m]) */
v[ m ].Re = ve[m].Re + z.Re;
v[ m ].Im = ve[m].Im + z.Im;
v[m + n / 2].Re = ve[m].Re - z.Re;
v[m + n / 2].Im = ve[m].Im - z.Im;
}
}
return;
}
void rfft(int32_t *data, int32_t max, int32_t *out, int32_t N)
{
complex *v;
complex *scratch;
int k;
v = calloc(N, sizeof(complex));
scratch = calloc(N, sizeof(complex));
for (k = 0; k < N; k++)
{
v[k].Re = (float)data[k] / max;
v[k].Im = 0;
}
fft(v, N, scratch);
for (int i = 0; i < N; i++)
out[i] = sqrt(v[i].Re * v[i].Re + v[i].Im * v[i].Im);
}