Я хотел бы лучше понять API FFTW. FFTW — это библиотека для вычисления дискретного преобразования Фурье (DFT) в одном или нескольких измерениях.
Теперь предположим, что у меня синусоида x = 30 * sin (2 * M_PI * f * i * T), где f — частота (например, f = 1000 Гц).
Если я использую функцию FFTW для анализа формы волны, я ожидаю получить одну частоту f = 1000 Гц.
У меня вопрос, как я могу сделать это в C ++ с помощью библиотеки FFTW?
Любая помощь будет оценена.
Вы можете найти более подробную информацию в Документация FFTW.
Тем не менее, для относительно простого случая одномерного действительного сигнала, следующее является суммой общих шагов, которые вы должны сделать.
Обычно вам нужно выделить буферы ввода / вывода и структуру данных, которую FFTW использует для своей собственной бухгалтерии, которую библиотека называет plan
, Это можно сделать несколькими способами (более подробно в документации FFTW), такими как:
#include "fftw3.h"
// First choose a buffer size:
// Typically best performance with a power of 2
// but could be a product of small primes
int input_size = 1024;
// Compute corresponding number of complex output samples
int output_size = (input_size/2 + 1);
// Allocate input and output buffers
double* input_buffer = static_cast<double* >(fftw_malloc(input_size * sizeof(double)));
fftw_complex* output_buffer = static_cast<fftw_complex*>(fftw_malloc(output_size * sizeof(fftw_complex)));
// Create plan
// Select plan creation flags
// see http://www.fftw.org/fftw3_doc/Planner-Flags.html#Planner-Flags
int flags = FFTW_ESTIMATE;
fftw_plan plan = fftw_plan_dft_r2c_1d(input_size,
input_buffer,
output_buffer,
flags);
Как только это будет сделано, вы можете заполнить input_buffer
с реальными образцами данных для анализа и выполнения БПФ с использованием:
fftw_execute(plan);
Комплексные результаты будут сохранены в output_buffer
, где output_buffer[0]
соответствует частоте 0, и output_buffer[output_size-1]
соответствует половине частоты дискретизации. Этот план может быть выполнен несколько раз (с обновленными значениями в input_buffer
, в результате чего соответственно обновляются значения в output_buffer
).
Обратите внимание, что, как правило, fftw_complex
(который является типом данных, используемым для выходных данных в этом примере) реализован как массив из 2 значений: индекс 0 соответствует действительной части, а индекс 1 соответствует мнимой части (например, output_buffer[i][0]
соответствует реальной части Iго частотная составляющая).
Как только вы закончите, вы можете освободить выделенные ресурсы с помощью:
fftw_free(input_buffer);
fftw_free(output_buffer);
fftw_destroy_plan(plan);
Обратите внимание, что если вы можете использовать float
, double
или же long double
версии этих функций. Просто ссылку на соответствующий libfftw3f-3.lib
, libfftw3-3.lib
или же libfftw3l-3.lib
,
Обновить: Если вы хотите использовать комплексные входные выборки вместе с fftw_plan_dft_1d
Затем вам нужно будет установить действительные и мнимые части следующим образом:
for (i = 0; i < N-1; ++i) {
t[i]=i*T;
signal[i][0] = 0.7 * sin(2*M_PI*f*t[i]); // real-part
signal[i][1] = 0.0; // imaginary-part
}
В качестве альтернативы измените тип входного сэмпла на float
, double
или же long double
(вместе с использованием fftw_plan_dft_r2c_1d
).
ваш вопрос относится к категории Одномерные ДПФ реальных данных
шаг 1: сгенерируйте данные формы сигнала, относящиеся к частоте 1000 Гц, с помощью предоставленной вами функции x = 30(2*pi*1000*id
(убедитесь, что частота выборки равна 2 × 2 * f, то есть 2000, я предлагаю вам повторить id по диапазону (0,1,1 / 2000)), что даст вам 2000 выборочных данных.
step2: используйте функцию, чтобы получить вывод dft
fftw_plan fftw_plan_dft_r2c_1d(int n, double *in, fftw_complex *out,
unsigned flags);