簡體   English   中英

在 C 中使用 fftw.h 計算 fft 和 ifft

[英]computing fft and ifft with fftw.h in C

大家好,我正在使用 fftw C 庫來計算嵌入式系統上某些信號處理應用程序的頻譜。 但是,在我的項目中,我遇到了一點阻礙。

下面是我編寫的一個簡單程序,以確保我正確實現了 fftw 功能。 基本上我想計算12個數字序列的fft,然后做ifft並再次獲得相同的數字序列。 如果您安裝了 fftw3 和 gcc ,則如果您使用以下代碼進行編譯,該程序應該可以工作:

gcc -g -lfftw3 -lm fftw_test.c -o fftw_test

目前我的 fft 長度與輸入數組的大小相同。

#include <stdio.h>
#include <stdlib.h>
#include <sndfile.h>
#include <stdint.h>
#include <math.h>
#include <fftw3.h>

int main(void)
{
double array[] = {0.1, 0.6, 0.1, 0.4, 0.5, 0, 0.8, 0.7, 0.8, 0.6, 0.1,0};
//double array2[] = {1, 6, 1, 4, 5, 0, 8, 7, 8, 6, 1,0};
double *out;
double *err;
int i,size = 12;

fftw_complex *out_cpx;

fftw_plan fft;
fftw_plan ifft;
out_cpx = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*size);
out = (double *) malloc(size*sizeof(double));
err = (double *) malloc(size*sizeof(double));

fft = fftw_plan_dft_r2c_1d(size, array, out_cpx, FFTW_ESTIMATE);  //Setup fftw plan for fft
ifft = fftw_plan_dft_c2r_1d(size, out_cpx, out, FFTW_ESTIMATE);   //Setup fftw plan for ifft

fftw_execute(fft);
fftw_execute(ifft);

//printf("Input:    \tOutput:    \tError:\n");
printf("Input:    \tOutput:\n");
for(i=0;i<size;i++)
{
err[i] = abs(array[i] - out[i]);    
printf("%f\t%f\n",(array[i]),out[i]);
//printf("%f\t%f\t%f\n",(array[i]),out[i],err[i]);
}

fftw_destroy_plan(fft);
fftw_destroy_plan(ifft);
fftw_free(out_cpx);
free(err);
free(out);
return 0;
}

產生以下 output:

Input:      Output:
0.100000    1.200000
0.600000    7.200000
0.100000    1.200000
0.400000    4.800000
0.500000    6.000000
0.000000    0.000000
0.800000    9.600000
0.700000    8.400000
0.800000    9.600000
0.600000    7.200000
0.100000    1.200000
0.000000    0.000000

所以很明顯,IFFT正在產生一些擴大的結果。 在此處找到的 fftw 文檔中: fftw docs about scaling 它提到了一些縮放,但是我使用的是“r2c”和“c2r”轉換,而不是 FFT_FORWARD 和 FFT_BACKWARD。 任何見解將不勝感激。

查看您使用的函數的精彩文檔,您會發現您正在使用 FFT_FORWARD 和 FFT_BACKWARD,並且確切地知道它的用途。 因此,您之前找到的縮放信息也適用於此。

很抱歉學究,但您的 out_cpx 大小不正確。 它應該是 size/2 + 1 而不是 size/2 + 1。這是因為真實信號的 FFT 是 Hermitian。 您可以通過將 out_cpx 初始化為某個隨機數(全部為 3.14159)來驗證我所說的內容。 向前和向后運行,然后從 size/2 + 1 打印出 out_cpx 到 size。 它不會改變。

http://www.fftw.org/fftw3_doc/Real_002ddata-DFT-Array-Format.html#Real_002ddata-DFT-Array-Format

r2c 和 c2r 與常規傅里葉變換基本相同。 唯一的區別是輸入和 output 數組都需要保存一半的數字。 請查看FFTW r2c 和 c2r手冊的最后一段。 因此,歸一化因子正是實際數組的元素數量,或者在您的情況下是可變size (== 12)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM