簡體   English   中英

我在MathNet.Numerics中的傅里葉變換(卷積)有什么問題? - C#

[英]What is wrong with my Fourier Transformation (Convolution) in MathNet.Numerics? - C#

我試圖使用MathNet.Numerics's FFT(快速傅立葉變換)在2個音頻文件之間進行簡單的卷積,但是在IFFT之后我得到了一些奇怪的背景聲音。

我測試了它是Convolution還是Transformations,這導致了問題,我發現問題已經在FFT - > IFFT(Inverze FFT)轉換中顯示出來了。

我的簡單FFT和IFFT代碼:

float[] sound; //here are stored my samples

Complex[] complexInput = new Complex[sound.Length];
for (int i = 0; i < complexInput.Length; i++)
{
      Complex tmp = new Complex(sound[i],0);
      complexInput[i] = tmp;
 }

MathNet.Numerics.IntegralTransforms.Fourier.Forward(complexInput);

//do some stuff

MathNet.Numerics.IntegralTransforms.Fourier.Inverse(complexInput);

float[] outSamples = new float[complexInput.Length];

for (int i = 0; i < outSamples.Length; i++)
     outSamples[i] = (float)complexInput[i].Real;

在此之后,即使我在FFT和IFFT之間沒有做任何事情, outSamples也會被一些奇怪的背景聲音/噪音破壞。

我錯過了什么?

目前執行的MathNet.Numerics.IntegralTransform.Fourier (見Fourier.csFourier.Bluestein.cs )使用Bluestein的算法對於任何FFT長度是不是2的冪。

該算法涉及創建一個Bluestein序列(包括與n 2成比例的項),使用以下代碼,版本高達3.6.0:

static Complex[] BluesteinSequence(int n)
{
  double s = Constants.Pi/n;
  var sequence = new Complex[n];

  for (int k = 0; k < sequence.Length; k++)
  {
    double t = s*(k*k); // <--------------------- (k*k) 32-bit int expression
    sequence[k] = new Complex(Math.Cos(t), Math.Sin(t));
  }

  return sequence;
}

對於大於n 46341的任何大小,本實現中的中間表達式(k*k)使用int算術(根據MSDN整數類型引用表的32位類型)計算,這導致k的最大值的數字溢出。 因此, MathNet.Numerics.IntegralTransfom.Fourier的當前實現僅支持輸入數組大小,其為2的冪或2的非冪,直到46341(包括)。

因此,對於大型輸入陣列,解決方法可能是將輸入填充到下一個2的冪。

注意 :這個觀察是基於3.6.0版本MathNet.Numerics ,雖然限制似乎一直存在於早期版本(在Bluestein序列碼並沒有改變顯著打算早在2.1.1版本)。


更新2015/04/26

在我發布了這篇文章並對github bugtracking的類似問題發表評論之后,這個問題很快就在MathNet.Numerics修復了。 該修補程序現在應該可以在3.7.0版中使用。 但請注意,出於性能原因,您仍可能需要填充2的冪,特別是因為您已經需要將零填充用於線性卷積。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM