After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 492098 - [GstFFT] Broken scaling
[GstFFT] Broken scaling
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other Linux
: Normal blocker
: 0.10.15
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2007-10-31 14:12 UTC by Sebastian Dröge (slomo)
Modified: 2007-11-06 11:57 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Sebastian Dröge (slomo) 2007-10-31 14:12:37 UTC
Hi,
currently GstFFT somehow scales the data given to kiss the wrong way (i.e. not at all). To make it possible to call a fft and on the same data an inverse fft and get the same data again some scaling is necessary, I have that fixed for the floating point data types locally but I'm still fighting with the fixed point implementations.

The missing scaling also resulted in wrong magnitude being calculated.

Bye
Comment 1 Sebastian Dröge (slomo) 2007-11-05 10:02:40 UTC
Ok, after some investigation it seems that the following might be a good solution:
a) Document that behaviour of _fft() and _inverse_fft(), i.e. for floating point that iFFT(FFT(x)) = x*nfft and for fixed point iFFT(FFT(X)) = x/nfft and that one has to apply the required scaling to get iFFT(FFT(x)) = x. For fixed point this will be rather hard though... think of overflows, etc :)

b) Fix the magnitude calculation or what I would currently prefer, drop the magnitude and phase calculation functions. Dropping them seems to make sense as it's a rather special use case that requires them and even the spectrum element has it's own implementation for them as it has special needs. When dropping them it might make sense to add an example on how to calculate the magnitude in the docs though...

What do you think?
Comment 2 Sebastian Dröge (slomo) 2007-11-06 07:49:47 UTC
Ok, now a bit better explaination ;)

First of all, take a look at http://en.wikipedia.org/wiki/Discrete_Fourier_transform

For floating point this can be taken more or less as a reference...
As can be seen there, you'll need a 1/nfft somewhere to get iFFT(FFT(x))==x behaviour. Our current implementation of the FFT does exactly that for floating point, so to a) get the original output back you have to either divide the FFT output by nfft or the iFFT output (as the FFT is linear it doesn't matter). b), to calculate the magnitude and get the gain for different frequency bins from that you also have to divide the output of the FFT by nfft to get proper results.



For fixed point things are unfortunately a bit more complicated as overflows can happen (sure, they can happen to floating point too but that's rather unlikely here). To quote kissfft upstream:

> Consider the case of a radix-2 fft. At every stage of the FFT there is
> an addition operation that causes word growth of 1 bit.
> So at each stage, there is a division by two to prevent the possibility 
> of overflow.  With log2(Nfft) stages, there is an overall division by 
> 2^log2(Nfft) == Nfft

So that's why you get iFFT(FFT(x)) = x/nfft. For getting the original input again you have to take special care with fixed point samples for this reasons. For example you could do the following:

- Analyse the time domain data and get the highest integer C that won't give a overflow if all samples are multiplied with it.
- Multiply them all with C.
- get FFT(x) = X.
- get iFFT(X) = C*x / nfft and multiply by nfft, divide by C.

This will always give you the original data back as accurate as possible.



So my proposal for 0.10.15 is to simply document this behaviour (it can't get much better for the above mentioned reasons) and remove the magnitude and phase calculation functions as they're pretty useless even for the spectrum element.
Comment 3 Tim-Philipp Müller 2007-11-06 11:14:45 UTC
> So my proposal for 0.10.15 is to simply document this behaviour (it can't get
> much better for the above mentioned reasons) and remove the magnitude and phase
> calculation functions as they're pretty useless even for the spectrum element.

Let's do that then.

Comment 4 Sebastian Dröge (slomo) 2007-11-06 11:57:49 UTC
2007-11-06  Sebastian Dröge  <slomo@circular-chaos.org>

        * docs/libs/gst-plugins-base-libs-sections.txt:
        * gst-libs/gst/fft/gstfftf32.c:
        * gst-libs/gst/fft/gstfftf32.h:
        * gst-libs/gst/fft/gstfftf64.c:
        * gst-libs/gst/fft/gstfftf64.h:
        * gst-libs/gst/fft/gstffts16.c:
        * gst-libs/gst/fft/gstffts16.h:
        * gst-libs/gst/fft/gstffts32.c:
        * gst-libs/gst/fft/gstffts32.h:
        * tests/check/libs/fft.c: (GST_START_TEST):
        Remove the magnitude and phase calculation functions as these have        very special use cases and can't even be used for the spectrum        element. Also adjust the docs to mention some properties of the used        FFT implemention, i.e. how the values are scaled. Fixes #492098.