ARM-software / CMSIS_5

CMSIS Version 5 Development Repository
http://arm-software.github.io/CMSIS_5/index.html
Apache License 2.0
1.33k stars 1.08k forks source link

Add example for real fft (rfft) #1091

Closed jerabaul29 closed 2 years ago

jerabaul29 commented 3 years ago

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?

jerabaul29 commented 3 years ago

A possible way to make things easier would be to extend this explanation:

https://github.com/ARM-software/CMSIS_5/blob/9ce90ae0d94ca6893dc6e03c53d8569e17eecedc/CMSIS/DSP/Source/TransformFunctions/arm_rfft_fast_f32.c#L564-L573

With some fftlen information as was done here for example:

https://github.com/ARM-software/CMSIS_5/blob/9ce90ae0d94ca6893dc6e03c53d8569e17eecedc/CMSIS/DSP/Source/TransformFunctions/arm_cfft_f32.c#L550

christophe0606 commented 3 years ago

@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.

jerabaul29 commented 3 years ago

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:

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...

jerabaul29 commented 3 years ago

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:

https://github.com/ARM-software/CMSIS_5/blob/9ce90ae0d94ca6893dc6e03c53d8569e17eecedc/CMSIS/DSP/Source/TransformFunctions/arm_rfft_fast_f32.c#L504-L505

Because this would imply the frequencies I wrote higher, which means loosing the information at the Nyquist frequency, right?

christophe0606 commented 3 years ago

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.

jerabaul29 commented 3 years ago

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.

christophe0606 commented 3 years ago

I am always interested to see new uses of the CMSIS-DSP.

jerabaul29 commented 3 years ago

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 :) .

christophe0606 commented 3 years ago

@jerabaul29 Let's keep it open. Issue tagged with "enhancement" will be done at some point.

christophe0606 commented 2 years ago

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.