我正在使用Exocortex.DSP库进行C#,它没有给我我期望的输出。我不确定为什么。我在这个例子中使用的音频文件是16位无符号.wav文件中的纯800Hz音调。在Audacity,我可以看到它只是一个正弦波。我将文件(使用NAudio)作为byte []接收,然后使用BitConverter.Single转换它。在阵列上运行Fourier.FFT后,我希望在样本[800]处看到重要数据并在其他地方看到零,但这与我得到的数据完全不同。这是代码......
public static void Main(string[] args)
{
var waveChannel = new WaveChannel32(new WaveFileReader("../../Files/800Hz.wav"));
var buffer = new byte[4096 * 4];
waveChannel.Read(buffer, 0, 4096 * 4);
var samples = new ComplexF[4096];
for (int i = 0; i < 4096; i++)
{
samples[i].Re = BitConverter.ToSingle(buffer, i * 4);
}
Fourier.FFT(samples, FourierDirection.Forward);
for (int i = 790; i < 810; i++)
Console.WriteLine(i + ": " + samples[i]);
}
...这给了我以下输出......
790: ( -0.4223004, -0.5940632i )
791: ( -0.4242424, -0.6004524i )
792: ( -0.4241259, -0.591617i )
793: ( -0.4438736, -0.5921871i )
794: ( -0.4386246, -0.5902517i )
795: ( -0.4222358, -0.6125283i )
796: ( -0.424219, -0.586903i )
797: ( -0.4283331, -0.6008587i )
798: ( -0.4152279, -0.5989774i )
799: ( -0.4329002, -0.5994851i )
800: ( -0.4230377, -0.5904933i )
801: ( -0.4128067, -0.5878658i )
802: ( -0.4171145, -0.5898319i )
803: ( -0.4254847, -0.572481i )
804: ( -0.4199851, -0.5827408i )
805: ( -0.4186496, -0.5890546i )
806: ( -0.4181305, -0.6026474i )
807: ( -0.4402256, -0.5738652i )
808: ( -0.4149643, -0.589726i )
809: ( -0.4256677, -0.599369i )
我还尝试计算每个复数的大小,看看是否会给我一些更重要的东西,但仍然得到类似的结果。我不确定我是否遗漏了代码中的某些内容,或者只是不了解结果。请帮忙吗?
答案 0 :(得分:4)
无法在signal[800]
FFT结果的N个复数样本具有频率范围
0 Hz .. Ns/2, with Ns = sampling frequency of your time signal
采样频率为44.1 kHz时,第一个FFT采样为0 Hz(DC),最后一个FFT采样为22.05 KHz(奈奎斯特频率)。
如果这是1024点FFT,您将获得512个复杂样本。所以两个FFT样本之间的距离是22050/512 == 43 Hz,所以你的800Hz线约为第18个样本。
<小时/> 的修改
为什么这些其他组件不等于0.0?
傅里叶变换假定循环输入。如果您的输入不是循环的,则必须应用一个窗口使输入有限(并且适合单个循环。)
如果您没有考虑开窗,您会自动应用一个矩形窗口:您的信号会突然开始&#34;在FFT开始时结束&#34;突然&#34;在FFT结束时。这使得一个矩形窗口。
现在,FFT结果恰好是输入信号(单峰)的傅里叶变换的卷积和这个矩形窗口的傅立叶变换(sinc == sin( x)/ x函数)。
因此,您所看到的单个正弦分量的FFT结果实际上是矩形窗口的傅里叶变换,即sinc函数,仅在几个点处为零。