Closed jerabaul29 closed 2 years ago
A possible way to make things easier would be to extend this explanation:
With some fftlen information as was done here for example:
@jerabaul29 Thanks for the feedback. The problem with examples is that they need to be maintained and retested for the releases.
I prefer to improve the documentation.
For the RFFT, you need to input a real signal. So no imaginary part.
x0 x1 x2 ... and not x0 0 x1 0 x2 0.
The latter signal would be complex with imaginary part to zero. The interest of the RFFT is to work on less values.
I see. I agree, better documentation / documentation easier on non experts for the RFFT functions would be great :)
That sounds good. So if I understand well, based on your comments and re-reading the comments:
float32_t * p : the input, but modified by the transform. should be in the format: x0 x1 ... xN-1 where each x is a float32_t
float32_t * pOut: the output, in the format: t0_real t0_imaginary t1_real t1_imaginary ... t[N/2-1]_real t[N/2-1]_imaginary
associated with frequencies:
frq_0=0: csst_offset frq_1=sample_frq/N frq_2=2sample_frq/N ... frq_N/2-1=(N/2-1)sample_frq/N
is this right? In this case everything is clear.
Sorry for asking in such a verbose way. It is just that it is easy to get confused about which format is used, and this creates weird problem down the way...
Also, does that mean that we loose the FFT coefficients ar frq_N/2 = sample_frq/2 = nyquist frequency? I was a bit surprised when I saw it here:
Because this would imply the frequencies I wrote higher, which means loosing the information at the Nyquist frequency, right?
It is well hidden in the documentation :-) for the f32 RFFT:
Except the first complex number that contains the two real numbers X[0] and X[N/2] all the data is complex. In other words, the first complex sample contains two real values packed.
So, for the RFFT F32, there is a kind of a hack and the first complex sample is packing more information.
For the Q31 and Q15 RFTT, it is different : the output has N+1 complex samples if the input has N real ones. And the last sample is real with a 0 imaginary part (but the output buffer must have enough space to contain this zero).
The comment you quoted above for the rfft_fast_f32 is accurate only if we take into account the previous remark that imag[0] is in fact containing real[N/2].
I agree, it is not very clean just to remove two words of storage from the output buffer. But because of backward compatibility, I can't change this.
Aaah, ok, I ha misunderstood that. Many thanks for your help, it is much clearer now :) . I agree, this is a bit confusing for just saving 2 float_32 of storage.
I hope that I get the time to do a "neat" project with your functions soon, in which case I will try to write a detailed blog post.
I am always interested to see new uses of the CMSIS-DSP.
If this is of interest for someone, I have a small recipe to poke at things (works fine with a Sparkfun Artemis Red Board and their "arduino core", except for the bug report #1189 ): https://github.com/jerabaul29/Artemis_MbedOS_recipes/blob/main/recipes/recipe_CMSIS_FFT_fft_init/recipe_CMSIS_FFT_fft_init.ino .
I do not think there is more to discuss here, many thanks for the explanations :) . Still letting it being open in case you want to remember to add some doc, but if you prefer to close, feel free :) .
@jerabaul29 Let's keep it open. Issue tagged with "enhancement" will be done at some point.
We are moving CMSIS-DSP to a new repository : https://github.com/ARM-software/CMSIS-DSP
I have recreated the github issues on the new repository (sometimes merging a few related ones). You can see the link just above this comment (... mentioned this issue ...).
So, I am closing the github issue here.
There is a very nice example of complex fft (cfft) available here:
https://github.com/ARM-software/CMSIS_5/blob/develop/CMSIS/DSP/Examples/ARM/arm_fft_bin_example/arm_fft_bin_example_f32.c
However, I was wondering how to take a real fft instead of a complex fft, and if it has any implications on how the data should be formatted as input.
For example, when performing the complex fft on a real signal as is done in the example, the data input is still complex numbers, where all the complex components are 0:
https://github.com/ARM-software/CMSIS_5/blob/develop/CMSIS/DSP/Examples/ARM/arm_fft_bin_example/arm_fft_bin_data.c
How should this example look like when performing a rfft transform? Should the input be formatted in the same way, or is it enough to only send the real part of the signal, without the all-0 complex part?