一个简单的fftw3例子:正弦信号的离散傅里叶变换

Table of Contents

1.源代码

2.编译运行

CMakeLists.txt

编译

运行

致谢


1.源代码

#include <complex.h>
#include <fftw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.141592653589793
#endif

int main(int argc, char* argv[]) {
    fftw_complex *in, *out;
    fftw_plan p;
    int n = 128;
    int f = 440;
    int r = 16000;
    int m = 1;
    double a = 1.;

    /* Read input */
    int c;
    while (1) {
        c = getopt(argc, argv, "n:f:a:r:m:h");
        if (c==-1) break;

        switch (c) {
            case 'n':
                n = atoi(optarg);
                if (n<2)
                    return 1;
                break;
            case 'f':
                f = atoi(optarg);
                if (f<0)
                    return 1;
                break;
            case 'r':
                r = atoi(optarg);
                if (r<0)
                    return 1;
                break;
            case 'm':
                m = atoi(optarg);
                if (m<0)
                    return 1;
                break;
            case 'a':
                a = atof(optarg);
                if (a<1.0)
                    return 1;
                break;
            case 'h':
                printf("usage: %s [options]\n"
                        "       -n int     Integer which specifies the array length.\n"
                        "       -f int     The frequency of the intput data.\n"
                        "       -r int     The sample rate.\n"
                        "       -a float   The amplitude.\n"
                        , argv[0]);
                return 0;
        }
    }

    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);

    /* Build input */
    double dt=1./r;
    double omega=2*f*M_PI;
    printf("Input:\n");
    int i;
    for (i=0; i<n; i++) {
        double t=i*dt;
        double y = a*sin(omega*t);
        in[i] = y;
/*    printf("%f %f %f\n", t, creal(in[i]), cimag(in[i]));*/
    }

    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
    p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE);

    for (int j=0; j<m; j++) {
        fftw_execute(p); /* repeat as needed */

        /* Print output */
        printf("Output Run %i:\n", j);
        for (i=0; i<n; i++) {
            int f=i*r/n;
            double a=creal(out[i])/n;
            double b=cimag(out[i])/n;
            double r=sqrt(a*a+b*b);
            printf("%d %f\n", f, r);
        }
    }

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

    return 0;
}

2.编译运行

CMakeLists.txt

cmake_minimum_required (VERSION 3.0)
project (main)
add_executable(main main.c)

target_link_libraries(main fftw3)
target_link_libraries(main m)
set_property(TARGET main PROPERTY C_STANDARD 99)

编译

$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Toa/fftw3/demo1

$ make
[ 50%] Building C object CMakeFiles/main.dir/main.c.o
[100%] Linking C executable main.exe
[100%] Built target main

运行

$ ./main.exe -h
usage: ./main [options]
        -n int     Integer which specifies the array length.
        -f int     The frequency of the intput data.
        -r int     The sample rate.
        -a float   The amplitude.

$ ./main.exe -n 10 -f 100 -a 10
Input:
Output Run 0:
0 1.746801
1600 0.623929
3200 0.327044
4800 0.237484
6400 0.201983
8000 0.192089
9600 0.201983
11200 0.237484
12800 0.327044
14400 0.623929

致谢

cspiel1

https://github.com/cspiel1/fftw_demos

相关:https://github.com/JabariBooker/FFTW-Demo

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
全波离散傅立叶变换(Full-Wave Discrete Fourier Transform,FW-DFT)和递推离散傅立叶变换(Recursive Discrete Fourier Transform,RDFT)是两种常见的离散傅立叶变换算法。 下面我将分别举例说明它们的应用场景和基本原理。 1. 全波离散傅立叶变换(FW-DFT): 全波离散傅立叶变换是一种将离散序列转换为频域表示的算法。它在一些信号处理和图像处理应用中被广泛使用。 举个例子,我们有一个长度为N的离散序列x[n],其中n表示序列的索引。通过FW-DFT算法,可以将x[n]转换为其频域表示X[k],其中k表示频率的索引。 FW-DFT的基本原理是将输入序列分解成N个基础函数(正弦和余弦),然后通过计算每个基础函数与输入序列的内积来得到频域表示。具体计算公式如下: X[k] = Σ(x[n] * e^(-i * 2π * k * n / N)) 其中,X[k]表示频域表示中第k个频率分量的幅度和相位信息。 2. 递推离散傅立叶变换(RDFT): 递推离散傅立叶变换是一种利用递推公式计算离散傅立叶变换的算法。它在一些实时信号处理和频谱分析应用中具有较高的效率。 举个例子,我们有一个长度为N的离散序列x[n],通过RDFT算法可以将其转换为频域表示X[k]。 RDFT的基本原理是利用递推关系将离散傅立叶变换的计算分解为多个步骤来提高计算效率。具体的递推公式如下: X[k] = X[k-1] + x[n] * W_N^(kn) 其中,W_N表示旋转因子,n表示输入序列的索引。 以上就是全波离散傅立叶变换和递推离散傅立叶变换的简单举例及其基本原理。这两种算法在信号处理和频谱分析领域都有广泛的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值