2015-11-12 365 views
3

我正在爲程序化音頻文件編寫一個應用程序,我必須分析我的新文件,得到它的頻譜並在計算中改變它。C#逆向FFT#

我想用快速傅立葉變換(FFT)做到這一點。這是我的遞歸C#FFT:

void ft(float n, ref Complex[] f) 
{ 
    if (n > 1) 
    { 
     Complex[] g = new Complex[(int) n/2]; 
     Complex[] u = new Complex[(int) n/2]; 

     for (int i = 0; i < n/2; i++) 
     { 
      g[i] = f[i * 2]; 
      u[i] = f[i * 2 + 1]; 
     } 

     ft(n/2, ref g); 
     ft(n/2, ref u); 

     for (int i = 0; i < n/2; i++) 
     { 
      float a = i; 
      a = -2.0f * Mathf.PI * a/n; 
      float cos = Mathf.Cos(a); 
      float sin = Mathf.Sin(a); 
      Complex c1 = new Complex(cos, sin); 
      c1 = Complex.Multiply(u[i], c1); 
      f[i] = Complex.Add(g[i], c1); 

      f[i + (int) n/2] = Complex.Subtract(g[i], c1); 
     } 
    } 
} 

鼓舞人心的例子是from wiki

然後我比較我與那些從wolframalpha對於相同的輸入0.6,0.7,0.8,0.9的結果,但結果是不一樣的。我的結果是Wolfram的兩倍,虛部是Wolfram的-2倍。

此外,維基表示FFT的逆可以與

this

來計算,但我比較輸入和輸出,它們是不同的。

有沒有人知道什麼是錯的?

+1

查找處理FFT的現有庫。不太確定您希望從其他人爲您調試代碼中獲得什麼。 –

+0

我想要一個有fft經驗的人,怎麼能解釋我如何得到fft的反例,例如使用其他算法,或者這是不可能的。我的代碼工作。我嘗試使用正弦和餘弦輸入並獲得正確的輸出。 –

回答

2

不同的實現經常使用離散傅里葉變換(DFT)的不同定義,並具有相應不同的結果。實現之間的對應通常相當簡單(比如縮放因子)。

更具體地說,你的實現是基於DFT的定義如下:

OP's DFT definition

在另一方面,Wolfram Alpha的默認使用a definition,其調整後從0開始的索引樣子:

Wolfram alpha default DFT definition

與此相對應,就可以改變你的執行的結果與匹配Wolfram Alpha的公司:

void toWolframAlphaDefinition(ref Complex[] f) 
{ 
    float scaling = (float)(1.0/Math.Sqrt(f.Length)); 
    for (int i = 0; i < f.Length; i++) 
    { 
    f[i] = scaling * Complex.Conjugate(f[i]); 
    } 
} 

現在只要使用正變換,直接執行公式

OP's inverse formula

你提供的是計算逆DFT:

void inverseFt(ref Complex[] f) 
{ 
    for (int i = 0; i < f.Length; i++) 
    { 
    f[i] = Complex.Conjugate(f[i]); 
    } 
    ft(f.Length, ref f); 
    float scaling = (float)(1.0/f.Length); 
    for (int i = 0; i < f.Length; i++) 
    { 
    f[i] = scaling * Complex.Conjugate(f[i]); 
    } 
} 

上調用ft原始序列0.6, 0.7, 0.8, 0.9應該因此得到您轉換的序列3, -0.2+0.2j, -0.2, -0.2-0.2j

在這個轉換序列上進一步調用inverseFt應該使您回到原始序列0.6, 0.7, 0.8, 0.9(在某個合理的浮點錯誤內),如this live demo所示。