IPB

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
How to use FFT to plot amplitude-frequency response?
midix
post Apr 17 2011, 11:39
Post #1





Group: Members
Posts: 5
Joined: 2-May 06
Member No.: 30299



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.

This post has been edited by midix: Apr 17 2011, 12:34
Go to the top of the page
+Quote Post
saratoga
post Apr 17 2011, 18:50
Post #2





Group: Members
Posts: 4715
Joined: 2-September 02
Member No.: 3264



QUOTE (midix @ Apr 17 2011, 06:39) *
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 wink.gif

Why did you pick 2^16 anyway?
Go to the top of the page
+Quote Post
midix
post Apr 17 2011, 19:43
Post #3





Group: Members
Posts: 5
Joined: 2-May 06
Member No.: 30299



QUOTE (saratoga @ Apr 17 2011, 12:50) *
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 blush.gif

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...
Go to the top of the page
+Quote Post
saratoga
post Apr 17 2011, 20:27
Post #4





Group: Members
Posts: 4715
Joined: 2-September 02
Member No.: 3264



QUOTE (midix @ Apr 17 2011, 14:43) *
QUOTE (saratoga @ Apr 17 2011, 12:50) *
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 blush.gif

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.
Go to the top of the page
+Quote Post
.alexander.
post Apr 17 2011, 23:01
Post #5





Group: Members
Posts: 73
Joined: 14-December 06
Member No.: 38681



Estimate impulse response. Trim it to 512 taps. Apply window and run FFT.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



RSS Lo-Fi Version Time is now: 17th April 2014 - 09:16