Hi I tested arm_rfft_fast_f32 function from CMSIS-DSP 1.4.4 with generated 50hz sine wave at 1000Hz sample rate using 1024 samples, but i get peek value at 102, not 51 which i should get 1000/1024 ~0,97 * 51 = 50Hz:
uint16_t i;
float32_t khz10[1024];
float32_t maxvalue;
uint32_t maxindex;
//float32_t output2[1024];
arm_rfft_fast_instance_f32 S;
arm_rfft_fast_init_f32(&S, 1024);
printf("Input=[");
for(i=0; i<1024; i++){
khz10[i] = 1.2f*arm_sin_f32(2*3.1415926f*50*i/1000)+1;
printf("%f,",khz10[i]);
}
printf("]\r\n");
arm_rfft_fast_f32(&S, khz10,khz10,0);
arm_abs_f32(khz10, khz10, 1024);
arm_max_f32(khz10+1, 1023, &maxvalue, &maxindex);
printf("Max:[%ld]:%f Output=[",maxindex,maxvalue);
I later tested this function with real data from adc and I can only get 1/4 of frequency spectrum
not about 1/2 as I expected. Can anyone could me explain this ?
Hi, i find what was wrong. We can't just use the same buffer for input and output in function arm_rfft_fast_f32
So the correct version looks like this:
float32_t output[1024];
arm_rfft_fast_f32(&S, khz10,output,0);
arm_cmplx_mag_f32(output,output, 512);
arm_max_f32(&output[1], 511, &maxvalue, &maxindex);
maxindex++;
printf("Max Value:[%ld]:%f Output=[",maxindex,maxvalue);
for(i=0; i<512; i++){ /**/
printf("%f,",output[i]);
I have aditional qestion about appling window functions
In book Joseph Yiu The Definitive Guide to ARM® Cortex®-M3 and Cortex®-M4 Processors
there example with using Hannning window
defined like:
// Create the Hanning window. This is usually done once at the
// start of the program.
for(i=0; i<L; i++) {
hanning_window_q31[i] =
(q31_t) (0.5f * 2147483647.0f * (1.0f - cosf(2.0f*PI*i / L)));
Why there is max integer value multiplied by 0.5. is this related with fixed point data type they use.
Can I just use max integer value from ADC which equals 4095 in stm32f4 ?
If i understand correctly in other windows function like Hamming we must also multiply equation by max value which can be obtained from ADC to suppress signal at the edges of buffer ?
Why he divide by L and not by L-1 ?
My previous reply is for your previous post containing the plot for the real and imaginary parts. I wonder why I didn't see your follow-up post and prior to my posting of this reply, it was your post that was shown as latest in the welcome page.
I pondered if it is possible to use the same buffer in arm_rfft_fast_f32. My attention was diverted from it because the signal and the spur has an interesting relationship. The frequency bin of the spur, 460, is equal to 511 - 51. Fortunately, you decided to restore the output buffer and found the trouble.
There is still a minor problem with the output spectrum. Earlier I stated that the CMSIS-DSP real FFT functions pack the data for frequency bins 0 (DC) and N/2 (Nyquist frequency) at the beginning of the output array. So if the output array is passed to arm_cmplx_mag_f32 right after arm_rfft_fast_f32, the magnitude for DC will be erroneous and the Nyquist frequency will be missing in the spectrum. We can have it corrected in two ways.
First, we use a temporary variable to save the Nyquist frequency data, later the saved data will be reinserted to the output array.
float32_t saveNyquist; // Variable for saving the Nyquist frequency data
// Take the absolute value of the Nyquist frequency data and save it to saveNyquist
arm_abs_f32(output+1, &saveNyquist, 1);
// Convert real DC data to complex number with imaginary part = 0,
// this 0 obliterates the Nyquist frequency data at index=1
// so it was saved in the preceding function call
output[1] = 0;
// Append the saved Nyquist frequency data
output[512] = saveNyquist;
// There are now 513 frequency bins because of the Nyquist frequency
// and it should be included in the search for the bin with maximum magnitude
arm_max_f32(output+1, 512, &maxvalue, &maxindex);
for(i=0; i<513; i++){
Second, instead of using a temporary variable, we extend the length of the output array to hold one more complex number. The Nyquist frequency data will be copied into the extended location.
float32_t output[1026];
// Unpack the DC and Nyquist frequency data
//
// Copy the Nyquist frequency data to the end of the buffer
output[1024] = output[1];
// Convert the DC and Nyquist frequency data to complex numbers
// with imaginary parts = 0
output[1] = output[1025] = 0;
arm_cmplx_mag_f32(output,output, 513);
Note: The corrections are with respect to the latest code that you posted, the one which you described as correct version.
Regarding the window functions, I'll just request that you post your questions in a new thread since the current discussion is already lengthy.