2009-11-03 3 views
0

Я сделал fft, чтобы получить базовую частоту в реальном времени и реализовать фильтры высокого и низкого частот.Как вычислить ifft из fft?

Теперь я хочу, чтобы иметь возможность записывать в .wav-файл после применения фильтра.

Сначала мне нужно будет инвертировать fft, и это мой вопрос. Каковы шаги для этого?

Я использую FFT, определенный в этом project.

Вот код для этого:

using System; 
using System.Collections.Generic; 
using System.Text; 

namespace SoundLog 
{ 
    public class FourierTransform 
    { 
     static private int n, nu; 

     static private int BitReverse(int j) 
     { 
      int j2; 
      int j1 = j; 
      int k = 0; 
      for (int i = 1; i <= nu; i++) 
      { 
       j2 = j1/2; 
       k = 2 * k + j1 - 2 * j2; 
       j1 = j2; 
      } 
      return k; 
     } 

     static public double[] FFT(ref double[] x) 
     { 
      // Assume n is a power of 2 
      n = x.Length; 
      nu = (int)(Math.Log(n)/Math.Log(2)); 
      int n2 = n/2; 
      int nu1 = nu - 1; 
      double[] xre = new double[n]; 
      double[] xim = new double[n]; 
      double[] magnitude = new double[n2]; 
      double[] decibel = new double[n2]; 
      double tr, ti, p, arg, c, s; 
      for (int i = 0; i < n; i++) 
      { 
       xre[i] = x[i]; 
       xim[i] = 0.0f; 
      } 
      int k = 0; 
      for (int l = 1; l <= nu; l++) 
      { 
       while (k < n) 
       { 
        for (int i = 1; i <= n2; i++) 
        { 
         p = BitReverse(k >> nu1); 
         arg = 2 * (double)Math.PI * p/n; 
         c = (double)Math.Cos(arg); 
         s = (double)Math.Sin(arg); 
         tr = xre[k + n2] * c + xim[k + n2] * s; 
         ti = xim[k + n2] * c - xre[k + n2] * s; 
         xre[k + n2] = xre[k] - tr; 
         xim[k + n2] = xim[k] - ti; 
         xre[k] += tr; 
         xim[k] += ti; 
         k++; 
        } 
        k += n2; 
       } 
       k = 0; 
       nu1--; 
       n2 = n2/2; 
      } 
      k = 0; 
      int r; 
      while (k < n) 
      { 
       r = BitReverse(k); 
       if (r > k) 
       { 
        tr = xre[k]; 
        ti = xim[k]; 
        xre[k] = xre[r]; 
        xim[k] = xim[r]; 
        xre[r] = tr; 
        xim[r] = ti; 
       } 
       k++; 
      } 
      for (int i = 0; i < n/2; i++) 
       //magnitude[i] = (float)(Math.Sqrt((xre[i] * xre[i]) + (xim[i] * xim[i]))); 
       decibel[i] = 10.0 * Math.Log10((float)(Math.Sqrt((xre[i] * xre[i]) + (xim[i] * xim[i])))); 
      //return magnitude; 
      return decibel; 
     } 
    } 
} 

ответ

2

Есть так много действительно хороших реализаций fft, таких как FFTW, которые я очень рекомендую использовать. Они также идут с ifft. Ваше, как реализовано, будет мучительно медленным.

+0

Скорость не является проблемой на данный момент. Мне нужно сделать это в C#, а FFTW имеет только C++. Можете ли вы рассказать мне, как я могу конвертировать то, что я написал PLZ? –

+0

Существует два отличия между прямым и обратным fts. Обратный должен быть масштабирован на 1/n, а экспонента отрицательна. Итак, для обратного ft (при условии, что я понимаю вашу реализацию) измените знак arg и умножьте каждую точку результата на 1/n. –

+0

Кроме того, вы используете сложный fft для реальных данных, установив все воображаемые на ноль. Это математически здорово, но расточительно. Посмотрите на веб-страницу Numerical Recipes (nr.com) для получения информации о реальных значениях ffts. –

-4

В зависимости от конкретной FFT и определения IFFT, разница только константа. Самый простой способ определить, что константа в вашем случае, вероятно, просто пробная ошибка &.

+0

Я использую FFT, определенный в этом Projecto: http://www.codeproject.com/KB/audio-video/SoundCatcher.aspx Можете ли вы мне помочь? –

+0

Испытание и ошибка? Посмотрите на мой комментарий выше. –

+0

-1 для "Trial & error"! – AAT