как сделать анализ спектра с FFTW?

Я хотел бы лучше понять API FFTW. FFTW — это библиотека для вычисления дискретного преобразования Фурье (DFT) в одном или нескольких измерениях.

Теперь предположим, что у меня синусоида x = 30 * sin (2 * M_PI * f * i * T), где f — частота (например, f = 1000 Гц).
Если я использую функцию FFTW для анализа формы волны, я ожидаю получить одну частоту f = 1000 Гц.

У меня вопрос, как я могу сделать это в C ++ с помощью библиотеки FFTW?
Любая помощь будет оценена.

1

Решение

Вы можете найти более подробную информацию в Документация 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).

5

Другие решения

ваш вопрос относится к категории Одномерные ДПФ реальных данных

шаг 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);
0

По вопросам рекламы [email protected]