Convert FFT to IFFT: Steps to Get Right Values Back

  • Thread starter btb4198
  • Start date
  • Tags
    Fft
In summary, you will need to go back to the original source of your algorithm to find out how it can be reversed.
  • #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.
 
Engineering news on Phys.org
  • #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
Views
2K
Replies
11
Views
3K
Replies
5
Views
3K
Replies
7
Views
3K
Replies
1
Views
3K
Replies
1
Views
1K
Replies
2
Views
2K
Back
Top