Я хотел бы лучше понять FFTW API. FFTW - это библиотека для вычисления дискретного преобразования Фурье (ДПФ) в одном или нескольких измерениях.
Теперь предположим, что у меня есть синусоидальная форма x = 30 * sin (2 * M_PI * f * я * 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
(который является fftw_complex
данных, используемым для вывода в этом примере) реализуется как массив из двух значений: индекс 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
ссылку на соответствующий 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
).
ваш вопрос относится к категории Одномерные ДПФ реальных данных
step1: генерировать данные осциллограммы в соответствии с частотой 1000hz с помощью функции, которую вы предоставили x = 30(2*pi*1000*id
(убедитесь, что частота выборки 2 раза 2 * f, что составляет 2000, я предлагаю вам повторить идентификацию по диапазону ( 0,1,1/2000)), который дает вам 2000 выборочных данных.
step2: используйте функцию для получения вывода dft
fftw_plan fftw_plan_dft_r2c_1d(int n, double *in, fftw_complex *out,
unsigned flags);