Convert FFT to IFFT: Steps to Get Right Values Back

  • Thread starter Thread starter btb4198
  • Start date Start date
  • Tags Tags
    Fft
Click For Summary
SUMMARY

The discussion focuses on converting a Fast Fourier Transform (FFT) implementation into an Inverse Fast Fourier Transform (IFFT) in C#. The key modification involves changing the sign in the complex exponential function used in the FFT. Specifically, the line in the Complex1 function should be altered from using a negative exponent to a positive exponent. Additionally, the input array must be reversed before passing it to the FFT function, and the output should be divided by the number of samples to achieve the correct IFFT results.

PREREQUISITES
  • Understanding of Fast Fourier Transform (FFT) and Inverse Fast Fourier Transform (IFFT)
  • Familiarity with complex numbers and their representation in programming
  • Knowledge of C# programming language and its syntax
  • Basic concepts of digital signal processing (DSP)
NEXT STEPS
  • Implement the IFFT by modifying the Complex1 function in your existing FFT code
  • Research the mathematical principles behind the inverse discrete Fourier transform (IDFT)
  • Explore normalization techniques for FFT and IFFT outputs
  • Study examples of FFT and IFFT implementations in C# for better understanding
USEFUL FOR

Software developers, digital signal processing engineers, and anyone working with Fourier transforms in C# who needs to implement or understand the conversion from FFT to IFFT.

  • #61
I don't quite understand the last part. If he is passing in N points and receiving N FFT bins then how can the indexing be spread over N-1 frequencies?
 
Engineering news on Phys.org
  • #62
Because DC is zero frequency in bin zero.
 
  • #63
If you have N bins and divide by (N-1), then don't you get two bins with the same normalized frequency?

I think what you want is N bins with normalized frequency [0:N-1]/N, right?
 
  • #64
when you say DC do you mean Direct current?
 
  • #65
Yes, that's why he said DC is zero frequency.
 
  • #66
ok i just did this:
Code:
1.0
-0.41614683654714241
-0.65364362086361194
0.960170286650366
-0.14550003380861354
-0.83907152907645244
0.84385395873249214
0.13673721820783361

those 8 number from
Cos(2 * n);
and that go into my fft and I get :
Code:
{(0.886399443294871, 0)}
{(0.862297845278363, 0.616189555028432)}
{(0.664289628322506, 2.35212587048179)}
{(1.42870222233886, -2.37880560416378)}
{(1.20302116482566, 0)}
{(1.42870222233886, 2.37880560416378)}
{(0.664289628322506, -2.35212587048179)}
{(0.862297845278363, -0.616189555028432)}
then I reverse and send it back to the fft and dived by N
and I get this :
Code:
0.99999999999999989
0.41614683654714235
0.65364362086361194
0.96017028665036586
0.14550003380861354
0.83907152907645233
0.84385395873249214
0.13673721820783363
I lost my - value , will they all are + now... but it is because I am taking the
Magnitude
I am doing
Code:
double[] returntemp = new double[R];
           for (int v = 0; v < R; v++)
           {
               F[v] = F[v].Magnitude / N;
               returntemp[v] = F[v].Magnitude;
           }
           return returntemp;
I did not know if I should use the real or imaginary numbers, so I just used the
Magnitude
is that ok ?
 
  • #67
If you want to verify that your FFT and IFFT are working correctly, you need to output both the real and imaginary parts. There will probably be a small imaginary part due to numerical errors but it should be negligible.

Your magnitudes look good.
 
  • #68
ok this is my real:
Code:
0.99999999999999989
-0.41614683654714235
-0.65364362086361194
0.96017028665036586
-0.14550003380861354
-0.83907152907645233
0.84385395873249214
0.13673721820783363
so I should use my real and not the Magnitude?
 
  • #69
my img is all like 0 and 0.00000000000000017478323165292
which is 0
 
  • #70
here are some video i make




see my fft does work for that site with the
(bin index/N) * fs * 2

also I did test it again with the new version of this site and it still work
 
Last edited by a moderator:
  • #71
Then that's good. Your original signal was all real, so it makes sense that any imaginary part that you get after your IFFT is just numerical error. The real part is the part you want to keep.
 
  • #72
btb4198 said:
here are some video i make




see my fft does work for that site with the
(bin index/N) * fs * 2

also I did test it again with the new version of this site and it still work

Did you ever figure out if your samples contain interleaved L+R stereo channels?
 
Last edited by a moderator:
  • #73
yes it is Stereo Channels.
I am read in Stereo data from the sound card

so my FFT and IFFT it working now...
thanks for all the help

but question about the *2

as you can see in the youtube video my fft is working the * 2

you think this has something to do with the fact I am using Stereo data ?
 
  • #74
I don't know how your library is extracting the stereo data, but sure it could explain the 2* factor. Interleaving the L+R channels would mean you have twice as many samples per second as you might think. If the signals look more or less the same, the interleaved data could look similar to a (noisy) sine wave of half the frequency.
 
  • #75
yes I think that is what it is doing and that is how it plays that will... that is why I can add 2*PI to play it.

ok I make a low pass filter:
Code:
       public void lowpass_filter( int frequency)
        {
 for (int i = 0; i < R; i++)
 {      
     if((i / N) * Fs >= frequency)
     {
         F[i] = 0D;
     }

 }  }

and it is working good from what I have been testing ...
but my high pass is not working?

Code:
public void hightpass_filter(int frequency)
        {
            for (int i = 0; i < R; i++)
            {
                if ((i / N) * Fs <= frequency)
                {
                    F[i] = 0D;
                }

            }

I still get both frequencies back
high and low
frequencies back


the lowpass filter is working so good
why it the high pass filter not?
 
  • #76
The problem is what I mentioned to you earlier — the frequencies in an FFT output appear in pairs. So instead of thinking of the frequencies as [0, 1, 2, …, N-1]/N, you need to think of them as [0, 1, …, N/2-1, -N/2, -N/2+1, …, -2, -1]/N. You always need to filter positive and negative frequency bins in pairs.

The lowpass kind of works because you are zeroing out all the bins higher than a certain number. However, you won't get back a pure real signal because all you have left are unpaired (low numbered) bins. The high pass doesn't work at all because you are removing a few low numbered bins, but the corresponding negative frequency bins are untouched.

Also, if you are dealing with stereo channels, what you really need to do is de-interleave the stream and then FFT/filter the two channels separately.
 
  • #77
ok how do I find the negative frequency bins?
I tried to google it, but I do not see anything ...
can you show me an example ?
I get that there are two part of a signal way, one - and +. but what I do not get is how with the high pass filter I can till getting the low Frequency.
I mean you use bin Index to get the frequencies right and and every bin is different so no two bins should get you the same Frequency right?
 
  • #78
look carefully at the [0, 1, 2, …, N-1]/N I posted above.

Let's say you have 8 samples at sampling rate fs = 8 Hz. The "normal" way you'd label your frequency bins is
[0, 1, 2, …, N-1]/N * fs = [0, 1, 2, …, 7]/8 * 8 Hz = [0, 1, 2, …, 7] Hz.

Since the frequencies wrap around the 8 Hz sampling frequency, these are exactly the same as
[0, 1, 2, …, N/2-1, -N/2, …,-2, -1,]/N * fs = [0, 1, 2, 3, -4, -3, -2, -1]/8 * 8 Hz = [0, 1, 2, 3, -4, -3, -2, -1] Hz.

If you do a quick test, you'll notice that the Fourier coefficients contained in the 1 and -1 Hz bins are just complex conjugates of each other. Similarly for 3, -3 Hz and every other pair of bins. This is because you have a real-valued signal. If you want to so something to your signal but keep it real-valued, you have to maintain this symmetry.

For example, to high pass keeping >= 2 Hz signals, you can zero the 0 Hz and +1, -1 Hz bins and then inverse transform.
 
  • #79
ok based off your last post I make this function :

Code:
 public void hightpass_filter(int frequency)
        {
          int i = 0;
          int t = 0;
            for (; i < R/2; i++)
            {
                if ((i / N) * Fs <= frequency)
                {
                    F[i] = 0D;
                }

            }
            for (; i < R; i++)
            {
                if ((t / N) * Fs <= frequency)
                {
                    F[i] = 0D;
                }

                t++;
            }
      
      }

but it is this not working...
I still see both Frequencies
so what did I do wrong ?
from 0 to N/2 is positive
and from N/2 to (N-1) is negative
right?
or did I not understand that right ?
 
  • #80
Try running the example from my post through this function. Just use double F[] = {0, 1, 2, 3, -4, -3, -2, -1} or something easily identifiable to fill the bins. I think you'll discover the issue.
 
  • #81
what Fs should i use?
because I am using 44100 and that is too high for only 8 points
after 1/N * 44100 is too high...

(never mind)
 
  • #82
Use any Fs for your test. You're just testing with synthetic data that you fully understand so that you can verify your code. I think my example above used 8 points at 8 Hz.
 
  • #83
ok I did what you said, but I am not see why it is now working:
ok I am using:
double[] list = { 0, 1, 2, 3, -4, -3, -2, -1 };
and
and I set the high pass filter to 2
and after doing it

I get
{(0, 0)}
{(0, 0)}
{(0, 0)}
{(4, -1.65685424949238)}
{(0, 0)}
{(0, 0)}
{(0, 0)}
{(4, 9.65685424949238)}

oh I am using fs = 8;

this is what I get before the filter:
1 10.452503719011
2 5.65685424949238
3 4.32956880116958

and this is what I get after the filter:
1 5.22625185950551
3 2.16478440058479

the 2 is done, but the 1 is this there
how 1 hz is bin 1 and bin 6 right?
are am I wrong about this ?

I also tried with Fs = 44100
I tried to filter out anything lower then 11000
i got:
{(0, 0)}
{(0, 0)}
{(-4, 4)}
{(4, -1.65685424949238)}
{(0, 0)}
{(0, 0)}
{(-4, -4)}
{(4, 9.65685424949238)}
this is before the filter:

5512.5 10.452503719011
11025 5.65685424949238
16537.5 4.32956880116958

and after the filter:
5512.5 5.22625185950551
11025 5.65685424949238
16537.5 2.16478440058479

5512.5 is divide by half
...
what i am missing here ?
 
  • #84
Look carefully. If your FFT output is { 0, 1, 2, 3, -4, -3, -2, -1 } and your frequencies are [ 0, 1, 2, 3, -4, -3, -2, -1 ] Hz, then a high pass that keeps only frequencies greater than 2 Hz should leave you with { 0, 0, 0, 3, -4, -3, 0, 0 }, which you then pass to your IFFT.
 
  • #85
hey,
i think it is working!
thanks,
 
  • #86
Great!
You're welcome.
 

Similar threads

  • · Replies 16 ·
Replies
16
Views
3K
  • · Replies 11 ·
Replies
11
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
23
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
1K
  • · Replies 2 ·
Replies
2
Views
2K