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

0

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

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

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

Теги:
fftw
spectrum

2 ответа

4
Лучший ответ

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

0

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

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);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню