Використання FFT у C/C++ для обробки сигналів
Дослідження продуктивності бібліотеки FFTW для обробки сигналів у C/C++ в порівнянні з Python. Висока ефективність використання ресурсів.

У світі обробки сигналів та аналізу даних важливу роль відіграє швидке перетворення Фур'є (FFT). Після порівняння реалізацій FFT на Python та C/C++, стало очевидно, що бібліотека C FFTW є найпотужнішою. Різниця в продуктивності між двома аналогічними програмами на Python та C/C++ виявилася значною, як за навантаженням на процесор, так і за використанням оперативної пам'яті. Це важливо, оскільки на моєму Raspberry Pi програма на Python заповнювала оперативну пам'ять до блокування системи.

Реалізація FFT у C
Для того щоб реалізувати FFT у C, я скористався RTLSDR для збору даних. Ось основні кроки, які я виконав:
- Підключення бібліотеки FFTW:
#include <fftw3.h> - Визначення розміру FFT:
#define CAPTURE 1000 // розмір FFT - Оголошення змінних:
fftw_complex *in; fftw_complex *out; fftw_plan p;
Налаштування FFT
Функція для налаштування FFT виглядає наступним чином:
void setFFT() {
in = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * CAPTURE + 1);
out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * CAPTURE + 1);
p = fftw_plan_dft_1d(CAPTURE, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
}
Обчислення спектру потужності
Функція для обчислення спектру потужності виглядає так:
double *fft(uint8_t *data, int *count, double *power_spectrum) {
double *power_spectrum_tmp = (double *) malloc(sizeof(double) * CAPTURE + 1);
fftw_complex *cx_power_spectrum = (fftw_complex *) malloc(sizeof(fftw_complex) * CAPTURE + 1);
int w = 0;
int x = 0;
// Перетворення даних у комплексний формат
for (int i = 0; i < CAPTURE * 2; i += 2) {
in[x][0] = (data[i] / (255.0 / 2.0)) - 1.0;
in[x][1] = (data[i + 1] / (255.0 / 2.0)) - 1.0;
x++;
}
fftw_execute(p);
// Обчислення спектру потужності
for (int i = 0; i < CAPTURE; i++) {
double complex complex_tmp = out[i][0] + out[i][1] * I;
complex_tmp = conj(complex_tmp) * complex_tmp;
cx_power_spectrum[w][0] = creal(complex_tmp);
cx_power_spectrum[w][1] = cimag(complex_tmp);
w++;
}
// Перетворення з комплексного формату в подвійний
for (int i = 0; i < CAPTURE; i++)
power_spectrum_tmp[i] = cx_power_spectrum[i][0];
// Реорганізація даних
for (int i = 0; i < CAPTURE / 2; i++)
power_spectrum[i] = power_spectrum_tmp[i + (CAPTURE / 2)];
for (int i = 0; i < CAPTURE / 2; i++)
power_spectrum[i + (CAPTURE / 2)] = power_spectrum_tmp[i];
free(power_spectrum_tmp);
free(cx_power_spectrum);
return power_spectrum;
}
Висновки
Використання FFTW у C/C++ дозволяє досягти значно кращої продуктивності в порівнянні з Python, що робить цю бібліотеку ідеальним вибором для обробки сигналів у реальному часі.



