0xAA55 发表于 2014-5-21 18:54:07

【C】C语言写的FFT算法的DLL(快速傅里叶变换)

所谓FFT在声音方面的应用就是,你给一个波形数据,它帮你从波形数据中判断各个频率波形的数量和振幅,也就是分频、频谱分析。
MP3的编码就是把WAV无损进行频谱分析,取得其中各个频段声波的量,进行筛选然后存储。因此MP3可以在损失音质的情况下把一首音乐压缩成较小的文件。
GoldWave这款软件右边的频谱图和声谱图就是用FFT算法算出来的,如下图。

大家可以通过看播放的时候各频段声波出现的范围和次数来判断你正在播放的音乐的音质。上图是无损。如果是320K的话,高音部分会有损失。如果是128K的话,那么大范围的声音部分都有损失。
这篇帖子将提供一个DLL给大家使用。这个DLL的作用是,你提供一段声波的数据(double浮点数数组),然后它还原这个声波数据的频谱。
此DLL只导出一个函数:FFT(32位_stdcall,可供VB等语言使用。)
原型://=============================================================================
//FFT:
//快速傅里叶变换算法实现。
//FFTSize:输入的波形数组的元素数和输出的复数数组的元素数。
//pWAVEIn:输入的波形数组指针
//pFFTOut:输出的FFT变换结果的虚数数组指针
//doInverse:是否做反转。
//返回实际处理的波形样本数量。
//-----------------------------------------------------------------------------
FFT_FUNC(unsigned)FFT
(
    unsigned    FFTSize,
    CxFloatP    pWAVEIn,
    ComplexP    pFFTOut,
    int         doInverse
);其中CxFloatP是这样定义的:typedef double CxFloat,*CxFloatP;然后ComplexP是这样定义的:#pragma pack(push,1)//统一字节对齐

typedef struct
{
    CxFloat R;//实数部分
    CxFloat I;//虚数部分
}Complex,*ComplexP;//复数

#pragma pack(pop)我承认我本人没有弄懂原理。我是从网上下载VB的代码,然后用自己的代码风格重写了一遍,编译了一个DLL。
最后运算的结果存储在Complex数组里。调用此函数的时候,pWAVEIn是CxFloat数组的指针,是输入的波形数据。 pFFTOut是Complex数组的指针,输出的虚数存储了频谱信息。CxFloat数组和Complex数组元素的个数都必须等于FFTSize的值。
得到的Complex数组经过计算它的模(复数的模的计算方法和二维向量的模的计算方法是一样的:平方根(实数部分×实数部分+虚数部分×虚数部分))可以得到频谱信息。注意Complex数组是左右对称的,意思是,模(pFFTOut)==模(pFFTOut)。
源码和下载地址回复可见。**** Hidden Message *****

jiu63577 发表于 2014-5-21 19:02:30

顶一个 话说这界面类似GoldWave 不会是下的部份源码吧

0xAA55 发表于 2014-5-21 21:26:19

jiu63577 发表于 2014-5-21 11:02
顶一个 话说这界面类似GoldWave 不会是下的部份源码吧
没仔细看帖子内容,警告一次
1、这个就是GoldWave的界面,不是我的程序,我的程序是DLL。
2、请仔细看标题,我给的不是界面,而是一个实现FFT算法的DLL。
3、这个FFT算法的原理是参考的一个VB的代码。我的程序和GoldWave没有半点关系。

秋月孝三 发表于 2014-5-22 14:21:52

FFT算法是一个蝶形的算法,其核心是分治,将其中重叠的部分只计算一次达到O(nlogn)的时间复杂度。该算法的用处非常大,他是整个信号处理的最重要组成部分,是空间域、时域,向频域转换的方法,当然,用到卷积或者多项式计算时,它可以将计算的复杂度降低。

langzhe 发表于 2017-11-12 20:10:38

niubiniubiniubi

Mr.Clumsy 发表于 2019-5-2 20:08:39

谢谢大佬,正在学习FFT方面的知识

moke 发表于 2021-8-5 19:00:09

厉害啊 A5
页: [1]
查看完整版本: 【C】C语言写的FFT算法的DLL(快速傅里叶变换)