我已经尝试了几周的时间来寻找解决方案,并且我确实已经阅读了与该主题相关的所有线程,所以我真的希望有人可以帮助我解决这个问题。
我想要做的是使用波形文件作为输入,对其进行傅里叶变换,然后将这些值与另一个文件进行比较并获得差异。
我长期以来一直致力于解决的挑战是如何使傅立叶变换发挥作用。
我只得到 NaN 值,而不是给我合理的结果。
我有以下代码:
public FFTPerformer(float[] soundvalues)
{
buffer = new System.Numerics.Complex[4096];
try {
for (int i = 0; i < 4096; i++)
{
System.Numerics.Complex tmp = new System.Numerics.Complex(soundvalues[i], 0);
buffer[i] = tmp;
}
}
catch(Exception ex)
{
System.Windows.MessageBox.Show("Es ist ein Fehler bei der Konvertierung des float arrays zum Complex-Array aufgetreten; " + ex.Message);
}
}
4096 通常会被更高的数字取代,该数字仍然是 2 的幂,但它甚至不能与该数字一起使用。
public void performFFT()
{
try
{
MathNet.Numerics.IntegralTransforms.Fourier.Forward(buffer, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
}
catch(Exception ex)
{
System.Windows.MessageBox.Show("Fehler: " + ex.Message);
}
}
更详细的描述: 我将长度设置为 4096 个值,因为这是两倍,并且该长度仅用于测试目的,因此这比使用数百万个值的原始声音文件进行检查要快一点;)所以这只是像这样,只要算法没有被证明有效。这也是出现奇怪的for循环的原因。即使是困难的 Math.Net 也使用 Bluestein 的算法来计算,无论如何都可以尝试使用两个数组的因子,因为即使它们使用任何其他算法 atm,它们也应该可以工作。
由于浮点十进制转换,尝试使用该 try-catch 获取错误消息,但它不会引发任何错误消息。
我现在的问题是,我在该 fft 中发送 4096 个复数,它们全部 Y=0,但 X 取决于音频文件(在另一个线程中读取音频 fft 不需要 Y 值,因此你应该将它们设置为 0)。所有 X 值都是普通浮点数,没有 NaN。但 FFT 仍然只是返回一个充满 NaN 的数组。
我首先尝试隐式转换为 System.Numerics.Complex,但没有成功,因此我使用 tmp 变量进行构造。
编辑: 我最终阅读了更多有关 FFT 算法的文章。 现在我仍然让我的声音值浮动并将它们转换为复杂数组。我检查了所有转换步骤的一致性,并且在该领域表现良好。所以我的问题是我是否真的只需要使用这个
MathNet.Numerics.IntegralTransforms.Fourier.Forward(buffer, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
或者如果我需要在此之前在 Math.NET 中进行干净的 FFT
为什么要先为
buffer
分配 4096 个元素,然后为每个元素分配一个 Complex ?这看起来不对。
只需设置
buffer[i].real = soundvalues[i]
、.imag=0
(从某种意义上说,不是字面意义上的。我不会“讲”C#)。
编辑:
https://msdn.microsoft.com/en-us/library/ee259559%28v=vs.110%29.aspx解释了从 Decimal 到 Complex 的隐式转换,将生成的复数设置为 (Decimal + 0i );这意味着你应该
for (int i = 0; i < 4096; i++)
{
buffer[i] = soundvalues[i];
}
我怀疑你的声音值仍然包含 NaN;也许您的输入有问题?