FFTW上手

準備

  • 下載FFTW源碼http://www.fftw.org/download.html(注意FFTW的GitHub源碼是不能直接拿來用的),我用的是3.3.8版本,即fftw-3.3.8.tar.gz
  • Deepin操作系統(deepin-15.11-amd64.iso)

安裝

$ ./configure
$ make
$ sudo make install

寫代碼

main.c:

#include <fftw3.h>
#include <math.h>

// sample dots
#define CONFIG_SAMPLEDOTS      (800)

// sample rate. unit: Hz
#define CONFIG_SAMPLERATE      (200)

// the input signal
#define CONFIG_INPUTSIGNAL(x)  (34.35 * sin(2 * PI * 11.19 * (x)) + 278.93 * sin(2 * PI * 52.46 * (x)) + 45.92)

#define PI                     (3.1415926)
#define REAL(x)                ((x)[0])        // x: fftw_complex *x; usage: REAL(x[3])
#define IMAG(x)                ((x)[1])        // x: fftw_complex *x; usage: IMAG(x[3])
#define ABS(x)                 sqrt((x)[0] * (x)[0] + (x)[1] * (x)[1])
#define STR1(R)                #R
#define STR2(R)                STR1(R)

int main(void) {
    double *in;
    fftw_complex *out;
    fftw_plan p;

    in = (double *)fftw_malloc(sizeof(double) * CONFIG_SAMPLEDOTS);
    out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * CONFIG_SAMPLEDOTS);

    // [1]! construct the input signal
    int i;
    for (i = 0; i < CONFIG_SAMPLEDOTS; i++) {
        in[i] = CONFIG_INPUTSIGNAL((double)i / CONFIG_SAMPLERATE);
    }

    // [2]! calculate the FFT
    p = fftw_plan_dft_r2c_1d(CONFIG_SAMPLEDOTS, in, out, FFTW_ESTIMATE);
    fftw_execute(p); /* repeat as needed */

    // [3]! print the output signal
    printf("the input signal f(t)=%s\n", STR2(CONFIG_INPUTSIGNAL(t)));
    printf("sample rate=%dHz\n", CONFIG_SAMPLERATE);
    printf("sample dots=%d\n", CONFIG_SAMPLEDOTS);
    printf("\n");
    printf("seq freq amp\n");
    printf("==============================\n");
    for (i = 0; i < CONFIG_SAMPLEDOTS / 2 + 1; i++) {
        if (i == 0) {
            printf("%d, %fHz, %f\n", i, (double)i / CONFIG_SAMPLEDOTS * CONFIG_SAMPLERATE, ABS(out[i]) / CONFIG_SAMPLEDOTS);
            continue;
        }
        printf("%d, %fHz, %f\n", i, (double)i / CONFIG_SAMPLEDOTS * CONFIG_SAMPLERATE, ABS(out[i]) * 2.0 / CONFIG_SAMPLEDOTS);
    }

    fftw_destroy_plan(p);
    fftw_free(in);
    fftw_free(out);

    return 0;
}

 

Makefile:

別忘了這個軟件是一定要鏈接fftw3這個庫的。

#----------------------------------------------------------------------
CFLAGS = -Wall -O0 -g

TARGET = test
SRC = ./main.c

INC = -I.

# you may need to add some archive lib here
# e.g:
#     ALIB = `$(CC) -print-file-name=libc.a` \
#            `$(CC) -print-file-name=libgcc.a`
ALIB =

# you may need to add some share lib here
# e.g:
#     SLIB = -lm \
#            -lfftw3
SLIB = -lfftw3 -lm

#----------------------------------------------------------------------
TARGET ?= target

OBJ = $(patsubst %.c, %.o, $(SRC))

$(TARGET) : $(OBJ)
	@echo "  Linking ..."
	@$(CC) $(OBJ) $(ALIB) $(SLIB) -o $(TARGET)
	@echo "  end"

%.o : %.c
	@echo "  Compiling ..."
	@$(CC) $(CFLAGS) $(INC) -o $@ -c $<
	@echo "  CC    "$<

clean :
	@rm -f $(TARGET) $(OBJ)
	@echo "  clean over"

運行

the input signal f(t)=(34.35 * sin(2 * (3.1415926) * 11.19 * (t)) + 278.93 * sin(2 * (3.1415926) * 52.46 * (t)) + 45.92)
sample rate=200Hz
sample dots=800

seq freq amp
==============================
0, 0.000000Hz, 46.276810
1, 0.250000Hz, 0.713780
2, 0.500000Hz, 0.714259
3, 0.750000Hz, 0.715062
4, 1.000000Hz, 0.716193
5, 1.250000Hz, 0.717659
6, 1.500000Hz, 0.719468
7, 1.750000Hz, 0.721632
8, 2.000000Hz, 0.724165
9, 2.250000Hz, 0.727083
10, 2.500000Hz, 0.730405
11, 2.750000Hz, 0.734155
12, 3.000000Hz, 0.738358
13, 3.250000Hz, 0.743045
14, 3.500000Hz, 0.748253
15, 3.750000Hz, 0.754022
16, 4.000000Hz, 0.760401
17, 4.250000Hz, 0.767444
18, 4.500000Hz, 0.775217
19, 4.750000Hz, 0.783794
20, 5.000000Hz, 0.793266
21, 5.250000Hz, 0.803736
22, 5.500000Hz, 0.815327
23, 5.750000Hz, 0.828187
24, 6.000000Hz, 0.842492
25, 6.250000Hz, 0.858455
26, 6.500000Hz, 0.876335
27, 6.750000Hz, 0.896453
28, 7.000000Hz, 0.919204
29, 7.250000Hz, 0.945088
30, 7.500000Hz, 0.974741
31, 7.750000Hz, 1.008987
32, 8.000000Hz, 1.048910
33, 8.250000Hz, 1.095966
34, 8.500000Hz, 1.152157
35, 8.750000Hz, 1.220311
36, 9.000000Hz, 1.304554
37, 9.250000Hz, 1.411147
38, 9.500000Hz, 1.550072
39, 9.750000Hz, 1.738256
40, 10.000000Hz, 2.006879
41, 10.250000Hz, 2.420332
42, 10.500000Hz, 3.136390
43, 10.750000Hz, 4.671539
44, 11.000000Hz, 10.260965
45, 11.250000Hz, 30.781117
46, 11.500000Hz, 5.638384
47, 11.750000Hz, 2.952375
48, 12.000000Hz, 1.930828
49, 12.250000Hz, 1.396966
50, 12.500000Hz, 1.072442
51, 12.750000Hz, 0.857439
52, 13.000000Hz, 0.707358
53, 13.250000Hz, 0.599275
54, 13.500000Hz, 0.520164
55, 13.750000Hz, 0.462000
56, 14.000000Hz, 0.419475
57, 14.250000Hz, 0.388849
58, 14.500000Hz, 0.367345
59, 14.750000Hz, 0.352824
60, 15.000000Hz, 0.343614
61, 15.250000Hz, 0.338404
62, 15.500000Hz, 0.336177
63, 15.750000Hz, 0.336149
64, 16.000000Hz, 0.337728
...
190, 47.500000Hz, 2.283245
191, 47.750000Hz, 2.397622
192, 48.000000Hz, 2.524827
193, 48.250000Hz, 2.667146
194, 48.500000Hz, 2.827441
195, 48.750000Hz, 3.009346
196, 49.000000Hz, 3.217546
197, 49.250000Hz, 3.458184
198, 49.500000Hz, 3.739481
199, 49.750000Hz, 4.072689
200, 50.000000Hz, 4.473635
201, 50.250000Hz, 4.965306
202, 50.500000Hz, 5.582419
203, 50.750000Hz, 6.379994
204, 51.000000Hz, 7.450733
205, 51.250000Hz, 8.963953
206, 51.500000Hz, 11.265345
207, 51.750000Hz, 15.187485
208, 52.000000Hz, 23.372902
209, 52.250000Hz, 51.047656
210, 52.500000Hz, 267.205144
211, 52.750000Hz, 36.748034
212, 53.000000Hz, 19.676848
213, 53.250000Hz, 13.410244
214, 53.500000Hz, 10.156462
215, 53.750000Hz, 8.163863
216, 54.000000Hz, 6.818234
217, 54.250000Hz, 5.848500
218, 54.500000Hz, 5.116464
219, 54.750000Hz, 4.544277
220, 55.000000Hz, 4.084740
221, 55.250000Hz, 3.707571
222, 55.500000Hz, 3.392448
223, 55.750000Hz, 3.125228
224, 56.000000Hz, 2.895761
225, 56.250000Hz, 2.696578
226, 56.500000Hz, 2.522055
227, 56.750000Hz, 2.367881
228, 57.000000Hz, 2.230696
229, 57.250000Hz, 2.107838
230, 57.500000Hz, 1.997177
231, 57.750000Hz, 1.896982
232, 58.000000Hz, 1.805838
233, 58.250000Hz, 1.722570
234, 58.500000Hz, 1.646203
235, 58.750000Hz, 1.575912
236, 59.000000Hz, 1.511001
237, 59.250000Hz, 1.450876
238, 59.500000Hz, 1.395027
239, 59.750000Hz, 1.343014
240, 60.000000Hz, 1.294456
241, 60.250000Hz, 1.249019
242, 60.500000Hz, 1.206413
243, 60.750000Hz, 1.166382
244, 61.000000Hz, 1.128699
245, 61.250000Hz, 1.093165
246, 61.500000Hz, 1.059601
247, 61.750000Hz, 1.027847
248, 62.000000Hz, 0.997763
249, 62.250000Hz, 0.969219
250, 62.500000Hz, 0.942101
251, 62.750000Hz, 0.916305
252, 63.000000Hz, 0.891737
253, 63.250000Hz, 0.868311
254, 63.500000Hz, 0.845951
255, 63.750000Hz, 0.824584
256, 64.000000Hz, 0.804148
257, 64.250000Hz, 0.784582
258, 64.500000Hz, 0.765832
259, 64.750000Hz, 0.747849
260, 65.000000Hz, 0.730587
261, 65.250000Hz, 0.714003
262, 65.500000Hz, 0.698060
263, 65.750000Hz, 0.682719
264, 66.000000Hz, 0.667949
265, 66.250000Hz, 0.653718

輸入輸出對比:

  時域信號強度 頻域信號強度
直流分量 45.92 46.27681
正弦信號1 頻率 11.19 11.25
振幅 34.35 30.781117
正弦信號2 頻率 52.46 52.5
振幅 278.93 267.205144

可參考我的項目地址https://github.com/David-Croose/PracticeFFTW.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章