Skip to main content

Topic: How to use FFT to plot amplitude-frequency response? (Read 8122 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
  • midix
  • [*]
How to use FFT to plot amplitude-frequency response?
I am a C++/C# programmer and not a good mathematician so FFT is like some black box to me.
I would like to get a plottable AFR (amplitude-frequency response) data, like the software like Rightmark Audio does:

http://www.ixbt.com/proaudio/behringer/3031a/fr-hf.png

Now I have already programmed a system which plays back a logarithmic swept sine (with short fade-in/fade-out to avoid sharp transitions) and records the response from the audio system. The response is a bit noisy (recorded in a pretty usual room with a simple electret microphone) and I record the entire response with some reserve on both ends of the swept sine.
I have converted the input data to float samples in range [-1...1].

Now the hardest part - feeding the recorded data into FFT and getting back the frequencies.

As far as I understand, I need to pad the input with zeros to 2^n, use audio samples as a real part of a complex numbers, set imaginary=0, and FFT will return frequency bins array whith half length of input data.

The problem is - I need about 512 frequency bins, there is no need for more. But my recorded audio buffer with zero padding to 2^n takes 65536 samples, so I'll get 32768 frequency bins! This seems to be an overkill.

What is the right way to feed chunks of my recorded swept sine and get back 512 frequency points which take into account all the data I passed in?
Or maybe it is not possible and I need to feed the FFT with entire 65536 at once to get back all the AFR data I need and then interpolate to 512 points?

Also what would be the right way to smooth the data and when to do it? As I understand, FFT does not like sharp amplitude changes. Now my recorded audio has some background noise and there surely will be a sharp transition between the last samples of noisy audio and the start of my padding zeroes. How should I smooth that to avoid splatter and to make my resulting look as smooth as the image in the link I have given?

For now I have found only C++/C# code examples which process data in very small chunks for realtme audio visualization.  But I would like to see an example how to take some free FFT library (I guess I'll use Ooura FFT, it is C and has C# port), feed the swept sine recording and get back some nice amplitude-frequency response.

Thanks in advance for any ideas.
  • Last Edit: 17 April, 2011, 07:34:25 AM by midix

  • saratoga
  • [*][*][*][*][*]
How to use FFT to plot amplitude-frequency response?
Reply #1
What is the right way to feed chunks of my recorded swept sine and get back 512 frequency points which take into account all the data I passed in?


If you want 512 points, the right solution is to use a 512 bin FFT.  You can use a bigger one and try to interpolate that back down, but this is the same as just using the correct size FFT to begin with

Why did you pick 2^16 anyway?

  • midix
  • [*]
How to use FFT to plot amplitude-frequency response?
Reply #2
Why did you pick 2^16 anyway?


because the length (in samples) of the audio signal is somewhere between 2^15 and 2^16 so when I pad it with zeroes to the nearest 2^n number, I get 2^16. It was the first idea that came to my mind because then I could feed all at once and grab the response with all the data in one chunk 

Yes, you definitely are right - the best way would be to create FFT of more appropriate size. The problem is that I have no idea how would I combine the response if I split audio in chunks with 1024 size - what do I do with the results?

For example, I take 1024 samples of audio, and then what do I do next? Do I need some preprocessing before I pass float[-1..1] samples to FFT?
I pass those 1024 samples to the FFT as a real parts of complex number and FFT returns back some array with results.
Then I pass again next 1024 samples to the FFT and get another array. How do I combine it with the previous results- sum them up, take average or what?
Finally I take tail of the audio, pad it with zeros to 1024 and take the last 512-size array from the FFT. Again - how to combine it with the previous data?

Also FFT libraries have a bunch of various FFT functions - Real, Complex, 1D, 2D... but what would be the most appropriate to use for plotting AFR from 32 bit float audio samples?

Anyway, it would be great to have some simple code/pseudo code to avoid the need to go and study DSP...

  • saratoga
  • [*][*][*][*][*]
How to use FFT to plot amplitude-frequency response?
Reply #3
Why did you pick 2^16 anyway?


because the length (in samples) of the audio signal is somewhere between 2^15 and 2^16 so when I pad it with zeroes to the nearest 2^n number, I get 2^16. It was the first idea that came to my mind because then I could feed all at once and grab the response with all the data in one chunk 

Yes, you definitely are right - the best way would be to create FFT of more appropriate size. The problem is that I have no idea how would I combine the response if I split audio in chunks with 1024 size - what do I do with the results?


If I understand correctly, you've got a sin sweep, you've recorded it, and you want to process it with a 512 point FFT (or something close to that size).  The problem is that instead of recording 512 points needed to give you the FFT size you want, you've recorded 65536 points, right?

Assuming you can't simply tolerate an oversampled frequency spectrum, probably the simplest thing to do is just use a 65536 point spectrum to sum every 32 points into 1 to generate a 512 point spectrum (or whatever number of points spectrum you want).  FWIW it would have been more computationally efficient to set the sweep speed and sampling rate of your original data acquisition to match the desired FFT size, but that can be tricky to get right and it doesn't sound like this is a performance sensitive application.

  • .alexander.
  • [*][*]
How to use FFT to plot amplitude-frequency response?
Reply #4
Estimate impulse response. Trim it to 512 taps. Apply window and run FFT.