如何使用FFT绘制wav文件的频谱

本文关键字:文件 wav 何使用 FFT 绘制 | 更新日期: 2023-09-27 18:27:03

注意:这不是重复的,我有特定的要求,除了相关的问题。

首先,我想像大胆一样绘制音频文件(.wav)的频谱(类似于:如何从傅立叶变换中绘制频谱)。

到目前为止,我已经能够读写wav文件了。但我的问题是,我不知道我需要传递给FFT函数的确切值。顺便说一句,我在C#中使用Exocortec进行FFT。FFT函数要求我传递一个具有正确大小(5121024,…我想是)的复数数组,一个可选的长度整数参数,以及傅立叶方向(向前/向后)。

具体问题:

  1. 来自外皮质库的Complex(类)有两个值,即Real和Imaginary。我有一个样本数组,那么哪个应该是真的,哪个应该是虚的
  2. 我有wav文件,所以长度应该是可变的。如何将其传递给FFT函数?我应该选择一个大小(512/104/etc),将整个样本划分为该大小,然后将所有样本传递给FFT吗
  3. 我怎么知道x轴上应该列出哪些频率
  4. 如何绘制FFT的数据?(我希望x轴是频率,y轴是分贝)

如果你不明白我的意思,那么试着使用Audacity,导入一个音频文件,然后单击分析>绘制频谱。这些都是想要重现的东西。请详细回答我的问题,因为我真的很想学习这个。我对此只有一点背景知识。我只是数字信号处理的新手。此外,请尽可能不要指引我去其他FFT网站,因为他们没有具体回答我的问题。


编辑:

我读了一些书,发现了如何对音频数据进行FFT,但只能用2的幂。那么,在一个长度不是2次方的音频文件中,我该如何做同样的事情呢?根据一些人的说法,我需要使用"窗口"。我也对它进行了一些搜索,发现它只需要波形的一部分就可以稍后处理。请记住,我想获得音频文件的FFT,而不是它的一部分。那么我现在该怎么办?请帮助:(

如何使用FFT绘制wav文件的频谱

签名是

public static void  FFT( float[] data, int length, FourierDirection direction )
  1. 您传递一个复数数组,表示为对。由于你只有实数(样本),你应该把样本放在数组中的偶数位置-data[0]、data[2]、data[4]等等。奇数位置应该是0,data[1]=data[3]=0
  2. 长度是要计算FFT的样本量,它应该正好是数据数组长度的一半。你可以对你的整个WAV或部分WAV进行FFT处理——这取决于你想看到什么。Audacity将绘制文件所选部分的功率谱,如果您希望这样做,请传递整个WAV或所选部分
  3. FFT将只显示高达采样率一半的频率。因此,您的值应该介于0和采样率的一半之间。值的数量取决于您的样本数量(样本数量将影响计算的精度)
  4. Audacity绘制了功率谱图。你应该取你收到的数组中的每个复数对,并计算它的ABS。ABS定义为sqrt(r^2+i^2)。每个ABS值将对应于一个频率

下面是一个工作代码的例子:

float[] data = new float[8];
data[0] = 1; data[2] = 1; data[4] = 1; data[6] = 1;
Fourier.FFT(data, data.Length/2, FourierDirection.Forward);

我给它4个样品,都一样。所以我希望只在频率0下得到一些东西。事实上,运行后,我得到了

data[0]==1,data[2]==1、data[4]==1和data[6]==1

其他为0。

如果我想使用复杂阵列过载

Complex[] data2 = new Complex[4];
data2[0] = new Complex(1,0);
data2[1] = new Complex(1, 0);
data2[2] = new Complex(1, 0);
data2[3] = new Complex(1, 0);
Fourier.FFT(data2,data2.Length,FourierDirection.Forward);

请注意,这里的第二个参数等于数组的长度,因为每个数组成员都是复数。我得到了和以前一样的结果。

我想我以前错过了复杂的过载。我似乎不太容易出错,使用起来更自然,除非你的数据已经成对出现。