I am currently developing a realtime FFT-analyzer and want to use the juce fft. Great and easy to use like all the other juce stuff. Thanks!
But there is a little thing, I don’t understand. For testing, I use a simple sawtooth signal and pass it through the fft and for the tests I choosed different fft-orders.
Actually, I have expected results that are similar only that they have different resolutions, but they differ more than expected. especially the amplitudes are quite noticeable.Take a look at the image.
the left uses the fft order 10 and the right the fft order 14. The aplitudes with order 14 are much higher. First I thought, it was my window function and I deactivated it. so the signal is as pure straight saw. Why is the right one much higher?
IIRC the magnitude of a frequency is the real part divided by the number of bins, but please double check.
It would explain, why you got a higher magnitude with a higher order FFT.
and to get the mags and phases I am using the standard functions…
forcedinline static float getMagnitude(dsp::Complex<float>& harmonic)
{
const float re = harmonic.real();
const float im = harmonic.imag();
return std::sqrt(re * re + im * im);
}
forcedinline static float getPhase(dsp::Complex<float>& harmonic)
{
const float re = harmonic.real();
const float im = harmonic.imag();
return std::atan(im / re);
}
What do you exactly mean? If I divide the real by the nums of bins before I convert it into mags and phases, the mags in the visualizer are moving up and down over time (sure, i decreased the width of the circle in the img-real field). I also tried to divide the magnitude by the number of bins (and multiplied it with a factor, to see them again on the screen, cause they’re getting very tiny ). So it doesn’t work for me. Something is missing.
By the way, did you know that you can simply use std::complex<float> as complex data type? Nothing technically wrong with what you are doing, but if you look into the juce dsp header you’ll find
so dsp::Complex<float> is in fact a std::complex<float>. This means that you can simply use std::abs and std::arg instead of your own getMagnitude and getPhase implementations – no need to reinvent what’s already existing and often it is a good idea to use the std library implementations which might be optimized to the maximum