DSPRelated.com
Forums

Problem: stuck with simple spectral analysis

Started by Andy August 13, 2003
I am just beginning to conquer the FFT stuff and I already need some major
help.

I would like to draw a very rough estimate of signal spectrum using Don's
FFT.

I do the following after running a chunk of data:

//----------------------------

for(unsigned int n=0; n < N/2-1; n++)
{
 float power = 20*log10( re[n] * re[n] + im[n] * im[n] );
}

//----------------------------

As I understand, I only need the first half of data since real input
produces "mirrored" FFT.

The problem is that compared to commercial spectrum analyzers, my results
make no sense. Relatively, the lower frequencies should have much more
power, while any component above 18K should be very, very small. What I get
is almost flat. You would never tell what frequency range you are in by
looking at the numbers. A quick code that draws the spectrum also confirms
it. I cannot see any power reduction in the high frequency range, and I
should. Also, I do try windowing, but it does not help. By the way, is this
hamming code correct? I wrote it myself so I would need to check with the
pros :-)

//----------------------------

void WindowFFTData(float* pLeft, float* pRight)
{
     for(unsigned int n = 0; n < N; n++)
    {
     const float Coeff = 0.54 - 0.46 * cos( 2 * M_PI * n / (N-1)  );
     pLeft[n] *= Coeff;
     pRight[n] *= Coeff;
    }
}

//----------------------------

I will appreciate any help, guys. Thank you.

-- 
Andy

"Andy" <none@none.com> wrote in message
news:xJv_a.48578$Sr6.8389@fe08.atl2.webusenet.com...
> I am just beginning to conquer the FFT stuff and I already need some major > help. > > I would like to draw a very rough estimate of signal spectrum using Don's > FFT. > > I do the following after running a chunk of data: > > //---------------------------- > > for(unsigned int n=0; n < N/2-1; n++) > { > float power = 20*log10( re[n] * re[n] + im[n] * im[n] ); > } > > //---------------------------- > > As I understand, I only need the first half of data since real input > produces "mirrored" FFT. > > The problem is that compared to commercial spectrum analyzers, my results > make no sense. Relatively, the lower frequencies should have much more > power, while any component above 18K should be very, very small. What I
get
> is almost flat. You would never tell what frequency range you are in by > looking at the numbers. A quick code that draws the spectrum also confirms > it. I cannot see any power reduction in the high frequency range, and I > should. Also, I do try windowing, but it does not help. By the way, is
this
> hamming code correct? I wrote it myself so I would need to check with the > pros :-) > > //---------------------------- > > void WindowFFTData(float* pLeft, float* pRight) > { > for(unsigned int n = 0; n < N; n++) > { > const float Coeff = 0.54 - 0.46 * cos( 2 * M_PI * n / (N-1) ); > pLeft[n] *= Coeff; > pRight[n] *= Coeff; > } > } > > //---------------------------- > > I will appreciate any help, guys. Thank you.
Andy, Many commercial analyzers use a log frequency scale. This means that equal divisions of the frequency scale have fewer or greater absolute bandwidths. Example: 1 octave resolution has 50Hz from 50 to 100Hz, 100Hz from 100 to 200Hz, etc. You didn't say what the spectral shape was in terms of frequency scale. So, if it has high per Hz energy at low frequencies on a linear scale and the per Hz energy decreases with frequency, it will have a flatter curve if the plot is converted to one with frequency resolution with a log basis. Fred
On 13-Aug-2003, "Fred Marshall" <fmarshallx@remove_the_x.acm.org> wrote:

> it will have a flatter curve if the > plot is converted to one with frequency resolution with a log basis.
Thanks for the reply, Fred. I am actually using the one in Sound Forge and you can switch between log an linear. In log, you are right, the curve is quite flat at most of the range. So, checking again, I am looking at the linear scale where, starting from 0 Hz to 22.05 Hz, power goes from about -64 to -120 dB. I guess that's relative power, but no matter - that's not the picture I get when trying to simulate it. The power does not reduce at high frequencies, for some reason. I went back to basics and made sure I am using the FFT right. I used an example from "Understanding DSP" by R. Lyons - my output is dead on. It is really baffling :0 -- Andy "Every nation has the government it deserves."
"Andy" <none@none.com> wrote in message
news:ruy_a.61272$Ll4.2775@fe14.atl2.webusenet.com...
> > On 13-Aug-2003, "Fred Marshall" <fmarshallx@remove_the_x.acm.org> wrote: > > > it will have a flatter curve if the > > plot is converted to one with frequency resolution with a log basis. > > Thanks for the reply, Fred. I am actually using the one in Sound Forge and > you can switch between log an linear. In log, you are right, the curve is > quite flat at most of the range. So, checking again, I am looking at the > linear scale where, starting from 0 Hz to 22.05 Hz, power goes from about > -64 to -120 dB. I guess that's relative power, but no matter - that's not > the picture I get when trying to simulate it. The power does not reduce at > high frequencies, for some reason. I went back to basics and made sure I
am
> using the FFT right. I used an example from "Understanding DSP" by R.
Lyons
> - my output is dead on. It is really baffling :0
Andy, Well, if your output is dead on, then what's the problem? Let's see ....... Oh! You said zero Hz! Well, that probably could be zero if you were to remove the average from the original data. If there's a large average, then that could "artificially" give a high value at zero Hz. I say artificially because there may simply be a large dc offset in the data that isn't representative of anything you're interested in. You've thrown in a bunch of things without explanation - so it's impossible to go further. 18K???, absolute numbers like -64 and -120dB, etc. What the heck is the signal you're analyzing? Fred
On 13-Aug-2003, "Fred Marshall" <fmarshallx@remove_the_x.acm.org> wrote:

> absolute numbers like -64 and -120dB
Heh, I did say I thought this is relative - my test segment is just a piece of music :) I try to keep away from the -92 dB mark unless I deal with noise :) I am mostly interested in getting a spectral signature that matches. I think you have a great point about DC. I will have to look into that further because that just might be it. Oh well, welcome to the world of DSP, where everything is a bit more complicated than it should be :-) -- Andy "Every nation has the government it deserves."
"Andy" <none@none.com> wrote in message news:<ruy_a.61272$Ll4.2775@fe14.atl2.webusenet.com>...
> On 13-Aug-2003, "Fred Marshall" <fmarshallx@remove_the_x.acm.org> wrote: > > > it will have a flatter curve if the > > plot is converted to one with frequency resolution with a log basis. > > Thanks for the reply, Fred. I am actually using the one in Sound Forge and > you can switch between log an linear. In log, you are right, the curve is > quite flat at most of the range. So, checking again, I am looking at the > linear scale where, starting from 0 Hz to 22.05 Hz, power goes from about > -64 to -120 dB. I guess that's relative power, but no matter - that's not > the picture I get when trying to simulate it. The power does not reduce at > high frequencies, for some reason. I went back to basics and made sure I am > using the FFT right. I used an example from "Understanding DSP" by R. Lyons > - my output is dead on. It is really baffling :0
Given that you are using Sound Forge as a reference I am assuming that you are attempting to make a real time analyzer that measures the power on a octave or third octave basis. I'm pretty sure this is what your reference would be doing. The bins that contain the your power spectrum estimate are of fixed bandwidth whereas you want to bin the energy in bands that have increasing bandwidth with increasing frequency (constant Q). If your using an FFT/periodogram to do this then you will need to combine multiple bins to form each band and most likely interpolate between bins at the low frequnecy end. If you weren't attempting to make an RTA then you could try the AtSpec demo version out as a reference to getting your code running the way you expect it to. Regards, Paavo Jumppanen Author of AtSpec : A 2 channel PC based FFT spectrum analyzer http://www.taquis.com
"Andy" <none@none.com> wrote in message
news:eVC_a.44772$gL3.20347@fe07.atl2.webusenet.com...
> > On 13-Aug-2003, "Fred Marshall" <fmarshallx@remove_the_x.acm.org> wrote: > > > absolute numbers like -64 and -120dB > > Heh, I did say I thought this is relative - my test segment is just a
piece
> of music :) I try to keep away from the -92 dB mark unless I deal with
noise
> :) > > I am mostly interested in getting a spectral signature that matches. I
think
> you have a great point about DC. I will have to look into that further > because that just might be it. Oh well, welcome to the world of DSP, where > everything is a bit more complicated than it should be :-)
Andy, Well everything should only be as complicated as it needs to be. Albert Einstein said: "everything should be as simple as it is, but not simpler." "Making the simple complicated is commonplace; making the complicated simple, awesomely simple, that's creativity." -- Charles Mingus It's a quest to keep things simple / understandable to the least sophisticated audience. I get a great kick out of helping folks "get it". Getting a spectral signature that "matches"?? That's a *very* tough problem if you need it to work well. Often there are too many matches compared to what you'd like. Depends on the situation a lot and on the expectations!! Fred
On 14-Aug-2003, PaavoJumppanen@iname.com (Paavo Jumppanen) wrote:

> If you weren't attempting to make an RTA then you could try the AtSpec > demo version out as a reference to getting your code running the way > you expect it to.
No no, not RTA - in SF it's under "Tools", where it analyzes the current selection. Ok, basic question: in theory, if I collect the average power of all components in FFT and plot them - is that my basic spectrum? Are there any catches to it? I mean, I went over the theory quite a few times, but I think the practical side has more to it than that. Sorry for not providing enough information in the beginning - I guess that goes to show you that I have little idea about what I am doing :) -- Andy
Andy wrote:
>
...
> everything is a bit more complicated than it should be :-) >
In home repair, that's called "The Mushroom Effect". Under different aliases, it's universal. Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;
Andy wrote:

> The problem is that compared to commercial spectrum analyzers, > my results make no sense. Relatively, the lower frequencies > should have much more power, while any component above 18K > should be very, very small. What I get is almost flat.
So your results still differ from Sound Forge's after checking your use of the routine. But have you checked if Don's FFT code itself is actually working properly? You might probe it with some simpler test signals than your music snippet (single sinusoids at various frequencies and amplitudes, for starters) and see if the results are sane.
> const float Coeff = 0.54 - 0.46 * cos( 2 * M_PI * n / (N-1) );
You should divide by N, not (N-1), as the latter duplicates the first window point which already belongs to the next cos period. Martin