Forums

Magnitudes drop when adding more

Started by overgaard January 29, 2006
Hi,

I've just "restarted" my interest in DSP and mainly FFT.
I'm using FFTW which I think is absolutely amazingly good! :)

I was playing around with FFT a few years back and I think I
remember stumbled on this problem back then too. The sad
part is - I don't remember if I solved it or not back then.
(what good memory, eh? hehe)

Anyway, I'm troubled with something I quite can't figure out.
I've done a test application that generates sinewaves and stores them
to a WAV-file. When I open the WAV-file and run FFTW on it and plot
a spectrum of it, it looks fine on frequency. BUT the magnitudes are
behaving strangely. If I have a single tone, lets say at 1000 Hz 
it show up at full scale. If I add one more tone, they BOTH drop in
magnitude. To doublecheck I opened the WAV file i Audacity and looked att
the spectrum there. It looks fine there even if I add three tones or
more.
But in my application, the more tones I add, the lower they ALL get.
Why is this? (ripping the hair of my head)

I'm using real to complex FFTW, eg. fftw_plan_dft_r2c_1d
and I am calculating the magnitudes with
sqrt((in_complex[i][0]*in_complex[i][0])+(in_complex[i][1]*in_complex[i][1]))*Normalize

which should translate to 

Magnitude = sqrt(re^2 + im^2) * Normalize

My normalizing is

Normalize = (sqrt(1.0/FFT_SIZE)) * (sqrt(1.0/FFT_SIZE));

I've tried a lot of "normalizers" (searched Comp.DSP) but I'm not a 100
percent sure this is the "right" normalizing.

Anyone has any idea why the magnitudes drop the more tones I add?
And of course, please tell me something about how to normalize correctly.
If I have a sine at 1000 Hz which peaks(-1.0 to 1.0) it would be
nice to get the spectrum to show about 1.0 in magnitude at the bin
for 1000 Hz.

Best regards // J�rgen





"overgaard" <jorgen@antistaten.se> wrote in message 
news:rISdnc0GibpOXUHeRVn-qQ@giganews.com...
> Hi, > > I've just "restarted" my interest in DSP and mainly FFT. > I'm using FFTW which I think is absolutely amazingly good! :) > > I was playing around with FFT a few years back and I think I > remember stumbled on this problem back then too. The sad > part is - I don't remember if I solved it or not back then. > (what good memory, eh? hehe) > > Anyway, I'm troubled with something I quite can't figure out. > I've done a test application that generates sinewaves and stores them > to a WAV-file. When I open the WAV-file and run FFTW on it and plot > a spectrum of it, it looks fine on frequency. BUT the magnitudes are > behaving strangely. If I have a single tone, lets say at 1000 Hz > it show up at full scale. If I add one more tone, they BOTH drop in > magnitude. To doublecheck I opened the WAV file i Audacity and looked att > the spectrum there. It looks fine there even if I add three tones or > more. > But in my application, the more tones I add, the lower they ALL get. > Why is this? (ripping the hair of my head) > > I'm using real to complex FFTW, eg. fftw_plan_dft_r2c_1d > and I am calculating the magnitudes with > sqrt((in_complex[i][0]*in_complex[i][0])+(in_complex[i][1]*in_complex[i][1]))*Normalize > > which should translate to > > Magnitude = sqrt(re^2 + im^2) * Normalize > > My normalizing is > > Normalize = (sqrt(1.0/FFT_SIZE)) * (sqrt(1.0/FFT_SIZE)); > > I've tried a lot of "normalizers" (searched Comp.DSP) but I'm not a 100 > percent sure this is the "right" normalizing. > > Anyone has any idea why the magnitudes drop the more tones I add? > And of course, please tell me something about how to normalize correctly. > If I have a sine at 1000 Hz which peaks(-1.0 to 1.0) it would be > nice to get the spectrum to show about 1.0 in magnitude at the bin > for 1000 Hz. > > Best regards // J&#2013266166;rgen
J&#2013266166;rgen, First of all, the normalization is up to you really. The most common normalization in DSP is NO normalization in the FFT and 1/N normalization in the IFFT. FFTW doesn't do that for you as I recall. 1/sqrt(N) in both directions is more typically used by physicists I believe. Another variation is 1/N in the FFT. For one unit cosine of some integer number of periods in the temporal epoch, what you should get are a *pair* of real frequency samples of magnitude N/2 each if there is no scaling in the FFT. So, if you want to see magnitudes of 1.0 for each frequency sample of a unit cosine in time, you should multiply the fft by 2/N and the ifft by N/2 (assuming that it is already normalized by 1/N) or by 1/2 if it's not scaled that way. In other words: Scale the FFTW IFFT by 1/N as a "normal thing" in order to switch from one transform space to another without worries - unless you're changing the value of N in there somewhere. Then, if you want to have some other normalization "on top" of that, normalize in both directions (inversely) according to what you want. So, that would be 2/N for the fft and N/2 for the ifft if you want unit cosines to have each sample in frequency of mangitude 1.0. For a sum of one unit cosines of some integer number of periods each in the temporal epoch, there will be no change to the above. That is, unless you change N and the scaling changes accordingly! Fred
overgaard wrote:
> Hi, > > I've just "restarted" my interest in DSP and mainly FFT. > I'm using FFTW which I think is absolutely amazingly good! :) > > I was playing around with FFT a few years back and I think I > remember stumbled on this problem back then too. The sad > part is - I don't remember if I solved it or not back then. > (what good memory, eh? hehe) > > Anyway, I'm troubled with something I quite can't figure out. > I've done a test application that generates sinewaves and stores them > to a WAV-file. When I open the WAV-file and run FFTW on it and plot > a spectrum of it, it looks fine on frequency. BUT the magnitudes are > behaving strangely. If I have a single tone, lets say at 1000 Hz > it show up at full scale. If I add one more tone, they BOTH drop in > magnitude. To doublecheck I opened the WAV file i Audacity and looked att > the spectrum there. It looks fine there even if I add three tones or > more. > But in my application, the more tones I add, the lower they ALL get. > Why is this? (ripping the hair of my head)
This COULD have to do with the .wav format. A few months ago I made some recordings in the .wav format. Somebody who helped me set up the experiment asked me if I wanted volume information or just the waveforms. I must admit that I did not understand exactly what he asked, but I interpreted the question as if the .wav format separates the waveforms and the volume/gain information. If that is correct, each individual tone must necessarily become weaker if the volume is to be kept constant. Don't take my word for this, though! Ask somebody who knows the .wav format. Rune
Rune Allnor wrote:

> Don't take my word for this, though! Ask somebody who knows the > .wav format.
Check out the info on http://www.wotsit.org... it might be useful. Ciao, Peter K.
Rune Allnor wrote:

> Don't take my word for this, though! Ask somebody who knows the > .wav format.
Check out the info on http://www.wotsit.org... it might be useful. Ciao, Peter K.
"Rune Allnor" <allnor@tele.ntnu.no> wrote in message 
news:1138567435.150149.246960@o13g2000cwo.googlegroups.com...
> > overgaard wrote: >> Hi, >> >> I've just "restarted" my interest in DSP and mainly FFT. >> I'm using FFTW which I think is absolutely amazingly good! :) >> >> I was playing around with FFT a few years back and I think I >> remember stumbled on this problem back then too. The sad >> part is - I don't remember if I solved it or not back then. >> (what good memory, eh? hehe) >> >> Anyway, I'm troubled with something I quite can't figure out. >> I've done a test application that generates sinewaves and stores them >> to a WAV-file. When I open the WAV-file and run FFTW on it and plot >> a spectrum of it, it looks fine on frequency. BUT the magnitudes are >> behaving strangely. If I have a single tone, lets say at 1000 Hz >> it show up at full scale. If I add one more tone, they BOTH drop in >> magnitude. To doublecheck I opened the WAV file i Audacity and looked att >> the spectrum there. It looks fine there even if I add three tones or >> more. >> But in my application, the more tones I add, the lower they ALL get. >> Why is this? (ripping the hair of my head) > > This COULD have to do with the .wav format. A few months ago I made > some recordings in the .wav format. Somebody who helped me set > up the experiment asked me if I wanted volume information or just the > waveforms. I must admit that I did not understand exactly what he > asked, > but I interpreted the question as if the .wav format separates the > waveforms > and the volume/gain information. > > If that is correct, each individual tone must necessarily become weaker > if the volume is to be kept constant. > > Don't take my word for this, though! Ask somebody who knows the > .wav format.
There's nothing mysterious about the wave (.wav) format, at least not with the most common linear PCM version. It simply stores the digitized signal as a series of (usually 16-bit) samples. Now if someone is doing additional normalization or AGC on the signal, it could have a similar effect. But that is totally separate from the wave format itself. The issue is most likely with your software that generates the tones. Perhaps when you generate multiple tones, the software automatically scales all the tones to avoid clipping? It is certainly true that you can't take a full-scale sine wave and add another full-scale sine wave with a different frequency without clipping the signal. I'm not sure what games Audacity plays when it displays its spectrum.
> >"overgaard" <jorgen@antistaten.se> wrote in message >news:rISdnc0GibpOXUHeRVn-qQ@giganews.com... >> Hi, >> >> I've just "restarted" my interest in DSP and mainly FFT. >> I'm using FFTW which I think is absolutely amazingly good! :) >> >> I was playing around with FFT a few years back and I think I >> remember stumbled on this problem back then too. The sad >> part is - I don't remember if I solved it or not back then. >> (what good memory, eh? hehe) >> >> Anyway, I'm troubled with something I quite can't figure out. >> I've done a test application that generates sinewaves and stores them >> to a WAV-file. When I open the WAV-file and run FFTW on it and plot >> a spectrum of it, it looks fine on frequency. BUT the magnitudes are >> behaving strangely. If I have a single tone, lets say at 1000 Hz >> it show up at full scale. If I add one more tone, they BOTH drop in >> magnitude. To doublecheck I opened the WAV file i Audacity and looked
att
>> the spectrum there. It looks fine there even if I add three tones or >> more. >> But in my application, the more tones I add, the lower they ALL get. >> Why is this? (ripping the hair of my head) >> >> I'm using real to complex FFTW, eg. fftw_plan_dft_r2c_1d >> and I am calculating the magnitudes with >>
sqrt((in_complex[i][0]*in_complex[i][0])+(in_complex[i][1]*in_complex[i][1]))*Normalize
>> >> which should translate to >> >> Magnitude = sqrt(re^2 + im^2) * Normalize >> >> My normalizing is >> >> Normalize = (sqrt(1.0/FFT_SIZE)) * (sqrt(1.0/FFT_SIZE)); >> >> I've tried a lot of "normalizers" (searched Comp.DSP) but I'm not a
100
>> percent sure this is the "right" normalizing. >> >> Anyone has any idea why the magnitudes drop the more tones I add? >> And of course, please tell me something about how to normalize
correctly.
>> If I have a sine at 1000 Hz which peaks(-1.0 to 1.0) it would be >> nice to get the spectrum to show about 1.0 in magnitude at the bin >> for 1000 Hz. >> >> Best regards // J&#2013266166;rgen > >J&#2013266166;rgen, > >First of all, the normalization is up to you really. >The most common normalization in DSP is NO normalization in the FFT and
1/N
>normalization in the IFFT. >FFTW doesn't do that for you as I recall. >1/sqrt(N) in both directions is more typically used by physicists I
believe.
>Another variation is 1/N in the FFT. > >For one unit cosine of some integer number of periods in the temporal
epoch,
>what you should get are a *pair* of real frequency samples of magnitude
N/2
>each if there is no scaling in the FFT. So, if you want to see
magnitudes
>of 1.0 for each frequency sample of a unit cosine in time, you should >multiply the fft by 2/N and the ifft by N/2 (assuming that it is already
>normalized by 1/N) or by 1/2 if it's not scaled that way. > >In other words: >Scale the FFTW IFFT by 1/N as a "normal thing" in order to switch from
one
>transform space to another without worries - unless you're changing the >value of N in there somewhere. > >Then, if you want to have some other normalization "on top" of that, >normalize in both directions (inversely) according to what you want. >So, that would be 2/N for the fft and N/2 for the ifft if you want unit >cosines to have each sample in frequency of mangitude 1.0. > >For a sum of one unit cosines of some integer number of periods each in
the
>temporal epoch, there will be no change to the above. That is, unless
you
>change N and the scaling changes accordingly! > >Fred > > >
Hi Fred and thanks for answering my "call"! :) Very interresting information you supplied me with. Much appreciated! =) Normalization with (2.0/N) does it perfectly now! Finally, Yes! Again, thanks for your reply! Best regards // J&#2013266166;rgen
> >overgaard wrote: >> Hi, >> >> I've just "restarted" my interest in DSP and mainly FFT. >> I'm using FFTW which I think is absolutely amazingly good! :) >> >> I was playing around with FFT a few years back and I think I >> remember stumbled on this problem back then too. The sad >> part is - I don't remember if I solved it or not back then. >> (what good memory, eh? hehe) >> >> Anyway, I'm troubled with something I quite can't figure out. >> I've done a test application that generates sinewaves and stores them >> to a WAV-file. When I open the WAV-file and run FFTW on it and plot >> a spectrum of it, it looks fine on frequency. BUT the magnitudes are >> behaving strangely. If I have a single tone, lets say at 1000 Hz >> it show up at full scale. If I add one more tone, they BOTH drop in >> magnitude. To doublecheck I opened the WAV file i Audacity and looked
att
>> the spectrum there. It looks fine there even if I add three tones or >> more. >> But in my application, the more tones I add, the lower they ALL get. >> Why is this? (ripping the hair of my head) > >This COULD have to do with the .wav format. A few months ago I made >some recordings in the .wav format. Somebody who helped me set >up the experiment asked me if I wanted volume information or just the >waveforms. I must admit that I did not understand exactly what he >asked, >but I interpreted the question as if the .wav format separates the >waveforms >and the volume/gain information. > >If that is correct, each individual tone must necessarily become weaker >if the volume is to be kept constant. > >Don't take my word for this, though! Ask somebody who knows the >.wav format. > >Rune > >
Hi Rune, Thanks for answering! :) I don't think there's a problem with the WAV format. I'm quite used to wav-files at low level, at least PCM ones. :) I use a library called libsndfile for reading/saving wav-files. Didn't feel like inventing the wheel again. ;) Since I use PCM mode the samples are just "stored", so I must too agree I am puzzled by what your friend meant with volume/waveform. I think the problem is when I actually create the sines. I guess I am missing something trivial. But thanks for the insight friend! :) Best regards // J&#2013266166;rgen
>"Rune Allnor" <allnor@tele.ntnu.no> wrote in message >news:1138567435.150149.246960@o13g2000cwo.googlegroups.com... >> >> overgaard wrote: >>> Hi, >>> >>> I've just "restarted" my interest in DSP and mainly FFT. >>> I'm using FFTW which I think is absolutely amazingly good! :) >>> >>> I was playing around with FFT a few years back and I think I >>> remember stumbled on this problem back then too. The sad >>> part is - I don't remember if I solved it or not back then. >>> (what good memory, eh? hehe) >>> >>> Anyway, I'm troubled with something I quite can't figure out. >>> I've done a test application that generates sinewaves and stores them >>> to a WAV-file. When I open the WAV-file and run FFTW on it and plot >>> a spectrum of it, it looks fine on frequency. BUT the magnitudes are >>> behaving strangely. If I have a single tone, lets say at 1000 Hz >>> it show up at full scale. If I add one more tone, they BOTH drop in >>> magnitude. To doublecheck I opened the WAV file i Audacity and looked
att
>>> the spectrum there. It looks fine there even if I add three tones or >>> more. >>> But in my application, the more tones I add, the lower they ALL get. >>> Why is this? (ripping the hair of my head) >> >> This COULD have to do with the .wav format. A few months ago I made >> some recordings in the .wav format. Somebody who helped me set >> up the experiment asked me if I wanted volume information or just the >> waveforms. I must admit that I did not understand exactly what he >> asked, >> but I interpreted the question as if the .wav format separates the >> waveforms >> and the volume/gain information. >> >> If that is correct, each individual tone must necessarily become
weaker
>> if the volume is to be kept constant. >> >> Don't take my word for this, though! Ask somebody who knows the >> .wav format. > >There's nothing mysterious about the wave (.wav) format, at least not
with the
>most common linear PCM version. It simply stores the digitized signal as
a
>series of (usually 16-bit) samples. Now if someone is doing additional >normalization or AGC on the signal, it could have a similar effect. But
that is
>totally separate from the wave format itself. > >The issue is most likely with your software that generates the tones.
Perhaps
>when you generate multiple tones, the software automatically scales all
the
>tones to avoid clipping? It is certainly true that you can't take a
full-scale
>sine wave and add another full-scale sine wave with a different frequency
>without clipping the signal. I'm not sure what games Audacity plays when
it
>displays its spectrum. > > >
Hi Jon, Doh, you hit the nail mate! :) How stupid was I? Of course I can't add two or more sines att full-scale with different frequency without clipping. Looking at my source code I found that I scaled the mixed result in an averaging way. I mean 1+1+1 can't be 1. *LOL* My code looked something like this (just an example) for (int i = 0; i < length; i++) { samples[i] = 1.0 * sin(2 * M_PI * i * frequency / samplerate) + sin(2 * M_PI * i * frequency / samplerate) / 2 } I hade to devide by 2 for two sines and devide by 3 for three sines to avoid clipping (not go above 1.0). I guess this is what caused my dropped magnitudes. I was too hooked on it was something in the FFT I guess. :) Thanks for the help! Best regards // J&#2013266166;rgen
"overgaard" <jorgen@antistaten.se> wrote in message 
news:ONadnSU0c_eoIkLeRVn-sw@giganews.com...
> >"Rune Allnor" <allnor@tele.ntnu.no> wrote in message >>news:1138567435.150149.246960@o13g2000cwo.googlegroups.com... >>> >> >>There's nothing mysterious about the wave (.wav) format, at least not > with the >>most common linear PCM version. It simply stores the digitized signal as > a >>series of (usually 16-bit) samples. Now if someone is doing additional >>normalization or AGC on the signal, it could have a similar effect. But > that is >>totally separate from the wave format itself. >> >>The issue is most likely with your software that generates the tones. > Perhaps >>when you generate multiple tones, the software automatically scales all > the >>tones to avoid clipping? It is certainly true that you can't take a > full-scale >>sine wave and add another full-scale sine wave with a different frequency > >>without clipping the signal. I'm not sure what games Audacity plays when > it >>displays its spectrum. >> >> > > Hi Jon, > > Doh, you hit the nail mate! :) > How stupid was I? Of course I can't add two > or more sines att full-scale with different frequency without clipping. > Looking at my source code I found that I scaled the mixed result in an > averaging way. I mean 1+1+1 can't be 1. *LOL* > > My code looked something like this (just an example) > > for (int i = 0; i < length; i++) { > samples[i] = 1.0 * sin(2 * M_PI * i * frequency / samplerate) + > sin(2 * M_PI * i * frequency / samplerate) / 2 > } > > I hade to devide by 2 for two sines and devide by 3 for three sines to > avoid clipping (not go above 1.0). I guess this is what caused my dropped > magnitudes. > I was too hooked on it was something in the FFT I guess. :) > Thanks for the help! > Best regards // J&#2013266166;rgen
Glad you figured it out. Sometimes the simplest things are the most overlooked. If you want, you could remove the scaling based on number if frequencies and instead do a arbitrary scaling by say 1/10. Then you could add up to 10 sine waves without clipping and verify that the FFT magnitude doesn't change when adding more frequencies. -- Jon Harris SPAM blocker in place: Remove 99 (but leave 7) to reply