- UID
- 1
- 精华
- 积分
- 76365
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
所谓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[i ])==模(pFFTOut[FFTSize-1-i])。
源码和下载地址回复可见。 |
|