fftw的使用

news2024/11/24 22:31:35

1、下载编译

官网:http://www.fftw.org/index.html

2、FFT基础知识

2.1 概念

  • FFT分辨率可以表示为:fs/Nfft
    频率分辨率的物理量就是:观测信号的时间窗长度, 时间窗越长(N大), 对应频率分辨率就越高。
    提高频率分辨率的两种方法:增加fft点数N(计算量大),降低采样率(时间分辨率降低了)。

  • 输出取N/2个频点,N点fft的输出值也是N个(对称的),故只取一半。

  • 时域上的补0相当于频域上的插值,通过补0增加的fft点数无法提高fft精度

  • 幅度、相位

  • 示例:fs =1024/10 N=1024 △f=0.1Hz

2.2 对1024个点的信号,做4次256点FFT和1次1024点FFT的区别

有信号如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

如果拆分成4个4点FFT,或者1个16点,其中的数学关系不能凭直觉发现,但是,如果把这段信号拆分成:

1 2 3 4 | 0 0 0 0 | 0  0  0  0 | 0  0  0  0
0 0 0 0 | 5 6 7 8 | 0  0  0  0 | 0  0  0  0
0 0 0 0 | 0 0 0 0 | 9 10 11 12 | 0  0  0  0
0 0 0 0 | 0 0 0 0 | 0  0  0  0 |13 14 15 16

然后做4次16点的FFT,那么这4次16点的FFT频谱叠加,最后得到的叠加后的频谱就=一次16点的FFT.
那么,问题就变成了: 1个带12个0的16点的FFT1个4点的FFT之间是什么关系?
1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0和1 2 3 4,他们的频谱,就相当于1234的4点频谱做插值成16个点.
至于0 0 0 0 5 6 7 8 0 0 0 0 0 0 0 0和5 6 7 8 之间的关系,你知道根据时移定理,对频谱乘一个e^-i2pikm相当于时域上延迟k个点:0 0 0 0 5 6 7 8 0 0 0 0 0 0 0 0可以变形为5 6 7 8 0 0 0 0 0 0 0 0 0 0 0 0
也就是说,4点4FFT与1点的16FFT的关系,大致相当于:

FFT(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)=插值(FFT(1,2,3,4))+插值(FFT(5,6,7,8))*时移+插值(FFT(9,10,11,12))*时移^2+插值(FFT(13,14,15,16))*时移^3

3、FFTW基础

3.1 基本函数

plan= fftw_plan_dft_1d(_N,_in,_out,FFTW_BACKWARD,FFTW_MEASURE);//配置计算计划
倒数第二个参数sign, FFTW_FORWARD:正变换 ;FFTW_BACKWARD:逆变换。
最后的一个参数flags,FFTW_MEASURE:表示先计算一些FFT并测量所用的时间,以便为大小为n的变换寻找最优的计算方法。

//c-c
fftw_plan fftw_plan_dft_1d(int n, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);
fftw_plan fftw_plan_dft_2d(int n0, int n1, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);
fftw_plan fftw_plan_dft_3d(int n0, int n1, int n2, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);
fftw_plan fftw_plan_dft(int rank, const int *n, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);
//r-c
fftw_plan fftw_plan_dft_r2c_1d(int n, double *in, fftw_complex *out, unsigned flags);
fftw_plan fftw_plan_dft_r2c_2d(int n0, int n1, double *in, fftw_complex *out, unsigned flags);
fftw_plan fftw_plan_dft_r2c_3d(int n0, int n1, int n2, double *in, fftw_complex *out, unsigned flags);
fftw_plan fftw_plan_dft_r2c(int rank, const int *n, double *in, fftw_complex *out, unsigned flags);
//r-r
fftw_plan fftw_plan_r2r_1d(int n, double *in, double *out, fftw_r2r_kind kind, unsigned flags);
fftw_plan fftw_plan_r2r_2d(int n0, int n1, double *in, double *out, fftw_r2r_kind kind0, fftw_r2r_kind kind1, unsigned flags);
fftw_plan fftw_plan_r2r_3d(int n0, int n1, int n2, double *in, double *out, fftw_r2r_kind kind0, fftw_r2r_kind kind1, fftw_r2r_kind kind2, unsigned flags);
fftw_plan fftw_plan_r2r(int rank, const int *n, double *in, double *out, const fftw_r2r_kind *kind, unsigned flags);

void fftw_execute(const fftw_plan p);
void fftw_execute_dft(const fftw_plan p, fftw_complex *in, fftw_complex *out);     
void fftw_execute_split_dft(const fftw_plan p, double *ri, double *ii, double *ro, double *io);     
void fftw_execute_dft_r2c(const fftw_plan p,double *in, fftw_complex *out);     
void fftw_execute_split_dft_r2c(const fftw_plan p, double *in, double *ro, double *io);
void fftw_execute_dft_c2r(const fftw_plan p, fftw_complex *in, double *out);
void fftw_execute_split_dft_c2r(const fftw_plan p, double *ri, double *ii, double *out);
void fftw_execute_r2r(const fftw_plan p, double *in, double *out);

单序列正反变换的归一化处理时:除以N/2

3.2数据类型

FFTW有三个版本的数据类型:double、float、long double,
使用方法如下:

  • 链接对应的库(比如libfftw3-3、libfftw3f-3、或ibfftw3l-3) 包含同样的头文件fftw3.h
    单精度 前缀 “-fftwf” 编译选项 “-lfftw3f”
    双精度 前缀 “-fftwl” 编译选项 “-lfftw3l”
  • 将所有以小写"fftw_“开头的名字替换为"fftwf_”(float版本)或"fftwl_"(long double版本)。
    比如将fftw_complex替换为fftwf_complex,
    将fftw_execute替换为fftwf_execute等。
  • 所有以大写"FFTW_"开头的名字不变,将函数参数中的double替换为float或long double

最后,虽然long double是C99的标准,但你的编译器可能根本不支持该类型,或它并不能提供比double更高的精度。

3、示例

Qt中用fftw对音频数据变换
全球最快的傅里叶变换算法(FFTW)

#include <fftw3.h>
     ...
{
    fftw_complex *in, *out;
    fftw_plan p;
    ...
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);    
	...
    p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);	//变换类型
    fftw_execute(p); 				// 执行变换
    ...
    fftw_destroy_plan(p);
    fftw_free(in); 
    fftw_free(out);
}

音频变换的例子:

	int N = filesize/2;     			//计算数据个数
	short *in_buf;						//自己存输入数据
	//为fft输入计算分配空间
	double * in = (double*)fftw_malloc(sizeof(double) * N);
	for(int i=0; i<N; i++)
	{
	   in[i] = in_buf[i]; 			 	//将pcm文件中的数据复制到fft的输入
	}
	
	//为fft输出算分配空间
	fftw_complex * out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);
	
	//进行fft变换,fftw_plan_dft_c2r_1d函数进行反变换
	fftw_plan p = FFTW3_H::fftw_plan_dft_r2c_1d(N, in, out, FFTW_ESTIMATE);
	fftw_execute(p);
	
	double dx3 = (double)SAMPLE_RATE / N;
	
	polt_1->xAxis->setRange(0, SAMPLE_RATE/2, Qt::AlignLeft);
	
	//根据FFT计算的复数计算振幅谱
	for( int i=0; i<N/2; i++ )
	{
	   double val = sqrt(out[i][0] * out[i][0] + out[i][1] * out[i][1]);
	   val = val / (N / 2);
	   polt_1->graph(0)->addData( dx3 * i, val );
	
	   if( val > val_max )
	   {
	       val_max = val;
	   }
	
	   double db = log(val);
	   //qDebug("frequency = %f, amplitude = %f, db = %f", dx3 * i, val / (N / 2), db);
	}
	
	polt_1->yAxis->setRange(val_max*0.6, val_max*1.2, Qt::AlignBottom);
	polt_1->replot();
	
	//根据FFT计算的复数计算相位谱
	polt_2->xAxis->setRange(0, SAMPLE_RATE/2, Qt::AlignLeft);
	polt_2->yAxis->setRange(0, 10, Qt::AlignBaseline);	
	for( int i=0; i<N/2; i++ )
	{
	   double val = atan2(out[i][1], out[i][0]);
	   polt_2->graph(0)->addData( dx3 * i, val );
	}
	polt_2->replot();
	
	//fftw销毁
	fftw_destroy_plan(p);	
	fftw_free(in);
	fftw_free(out);

N点的FFT,以 “采样率/N” 为频率间隔,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/574866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python循环与内存管理

Python循环与内存管理 在编写Python代码时&#xff0c;循环是不可避免的。但是循环&#xff0c;特别是无限循环&#xff0c;会导致内存问题&#xff0c;影响程序性能及其稳定性。本文将重点介绍Python循环和内存管理。 Python循环 在Python中&#xff0c;有三种循环结构&…

史上最全Android性能优化方案解析

Android中的性能优分为以下几个方面&#xff1a; 布局优化 网络优化 安装包优化 内存优化 卡顿优化 启动优化 …… 一.布局优化 布局优化的本质就是减少View的层级。常见的布局优化方案如下&#xff1a; 在LinearLayout和RelativeLayout都可以完成布局的情况下优先选择LinearL…

chatgpt赋能python:Python如何清理输出的屏幕?

Python 如何清理输出的屏幕&#xff1f; 在 Python 编程中&#xff0c;我们经常需要在控制台上输出一些信息。但是当输出信息过多时&#xff0c;控制台的屏幕可能会变得很杂乱。这时候&#xff0c;我们就需要清理掉原有的输出内容&#xff0c;以便更好地展示新的信息。那么&am…

26 VueComponent 其他属性的更新

前言 这是最近的碰到的那个 和响应式相关的问题 特定的操作之后响应式对象不“响应“了 引起的一系列的文章 主要记录的是 vue 的相关实现机制 呵呵 理解本文需要 vue 的使用基础, js 的使用基础 测试用例 比如这里看一下 class 的更新 测试用例如下, 增加 topClazz …

使用stable diffusion webui时,安装gfpgan失败的解决方案(windows下的操作)

1.问题描述 初次打开stable diffusion webui时&#xff0c;需要安装gfpgan等github项目。但在安装gfpgan时&#xff0c;显示RuntimeError: Couldnt install gfpgan 2.解决方案 无法安装gfpgan的原因是网络问题&#xff0c;就算已经科学上网&#xff0c;并设置为全局&#x…

imPlot的使用

1、概述 https://github.com/epezent/implot https://github.com/ocornut/imgui

【PWN · ret2libc】[NISACTF 2022]ezstack

一道简单的ret2libc——对标wiki的ret2libc1 目录 前言 一、题目信息 1.查看保护 2.IDA反汇编 3.pwntools获取表信息 & "/bin/sh"信息 二、exp 总结 前言 通过查看ELF文件信息&#xff0c;确定攻击方法&#xff0c;实现ret2libc1类型的攻击 一、题目…

强连通分量(SCC, Strongly Connected Components)

强连通分量&#xff08;SCC, Strongly Connected Component&#xff09; 强连通分量的概念强连通分量的应用强连通分量的算法——Tarjan算法 强连通分量的概念 在有向图中&#xff0c;任意两个顶点 v i v_i vi​ 和 v j v_j vj​ 互相可达&#xff08;也即存在路径 v i → v…

chatgpt赋能python:Python如何连接数据库?

Python如何连接数据库&#xff1f; Python作为一种高级编程语言&#xff0c;已经被广泛应用于数据科学和Web开发。连接数据库是Python的一项重要功能&#xff0c;可以使我们的代码访问各种数据源来收集、分析和存储数据。在这篇文章中&#xff0c;我们将介绍Python如何连接各种…

chatgpt赋能python:Python循环等待用户输入:提高交互性和可靠性

Python 循环等待用户输入&#xff1a;提高交互性和可靠性 作为一种高级编程语言&#xff0c;Python 可以通过很多方式实现与用户进行交互&#xff0c;其中最基础的方式是等待用户输入。在开发基于文本界面的应用程序、命令行工具或脚本时&#xff0c;这种输入等待机制可以提高…

JDK8 新特性 Stream API 进阶 (结合案例详解--通透--讲清)

&#x1f473;我亲爱的各位大佬们好&#x1f618;&#x1f618;&#x1f618; ♨️本篇文章记录的为 JDK8 新特性 Stream API 进阶 相关内容&#xff0c;适合在学Java的小白,帮助新手快速上手,也适合复习中&#xff0c;面试中的大佬&#x1f649;&#x1f649;&#x1f649;。 …

ruoyi-vue版本(十八)创建自己的项目,使用若依里面的技术,多数据源的实现

目录 1 创建自己的项目2 连接MySQL数据库(多数据源)2.1 若依实现多数据源2.1.1 主要思想2.2 第三方的依赖的实现1 创建自己的项目 1 创建一个空文件夹 2 idea 里面创建项目

GPU云服务器Stable Diffusion搭建保姆级教程

搭建Stable Diffusion最大门槛就是GPU。许多人的电脑配置太低&#xff0c;根本无法搭建。或者即使搭建出来&#xff0c;但是跑图太慢。说多了不通过&#xff0c;看下图。 选择服务器 我选择的是境外GPU服务器&#xff0c;windows版本&#xff08;73.59元&#xff09;。linux会…

SQL进阶教程读后总结与感想

1. 基本信息 SQL进阶教程 [日]MICK 人民邮电出版社,2017年11月出版&#xff0c;1版 1.1. 读薄率 书籍总字数455千字&#xff0c;笔记总字数25820字。 读薄率25820455000≈5.67% 1.2. 读厚方向 SQL权威指南&#xff08;第4版&#xff09; SQL解惑&#xff08;第2版&…

数据库数据量大了怎么办? 当然是分库分表,Sharding-JDBC了解一下?

Sharding-JDBC是一款基于JDBC规范的分布式数据库中间件&#xff0c;可以帮助Java应用轻松实现水平分库分表、读写分离等分布式数据库功能&#xff0c;并提供了方便易用、高可用、高性能的数据访问解决方案。本文将从以下几个方面进行详细介绍&#xff1a; Sharding-JDBC的原理…

chatgpt赋能python:Python录屏录音介绍

Python录屏录音介绍 在日常工作和学习中&#xff0c;录制屏幕和录制音频是一件很常见的事情。Python语言拥有强大的生态系统和第三方库支持&#xff0c;也可以轻松实现录制屏幕和录制音频的功能。本篇文章将介绍如何使用Python语言实现录屏录音功能。 Python录屏 录制屏幕可…

numpy包中的取余函数和取模函数numpy.remainder()numpy.mod()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 numpy包中的取余函数和取模函数 numpy.remainder() numpy.mod() 下列代码中np.remainder(m,2)输出的结果是&#xff1f; import numpy as np m np.array([4, 5, 6]) print("【显示】m &…

chatgpt赋能python:Python局部导入:提升代码效率与性能

Python 局部导入: 提升代码效率与性能 Python 是一种强大的编程语言&#xff0c;为开发者提供了许多工具和库&#xff0c;以简化开发过程。在项目中&#xff0c;对于复杂的代码文件&#xff0c;Python 的模块化设计可以让我们将代码分解为更小的组件&#xff0c;以便更好地维护…

chatgpt赋能python:Python的声音处理能力

#Python的声音处理能力 Python 是一种多功能编程语言&#xff0c;强有力的功能和库使它成为一种广泛使用的工具。Python也可以用于处理声音。在本文中&#xff0c;我们将深入了解Python的声音处理能力&#xff0c;并介绍使用Python处理声音的一些库和工具。 ##声音处理的步骤…

chatgpt赋能python:Python循环等待:什么是它?如何解决?

Python 循环等待&#xff1a;什么是它&#xff1f;如何解决&#xff1f; 在 Python 编程中&#xff0c;循环等待是一种常见的问题。它发生在代码一直等待某个操作的结果&#xff0c;而这个结果却永远不会到来。这种情况会导致程序停顿或挂起&#xff0c;从而影响整个应用程序。…