/** Measures count of FFT calculations in one second. */ static void fft_measure_rate(void) { uint32_t time, count; arm_rfft_fast_init_f32(&rfft, FFT_SIZE); memset(fft_out, 0, sizeof(fft_out)); count = 0; time = timer_ms; while ((timer_ms - time) < 1000) { arm_rfft_fast_f32(&rfft, fft_in, fft_out, 0); count++; } debug_printf("fft done - calculations per sec: %d\n", count); }
void runFFT() { int32_t startTime, stopTime, totalTime; float32_t maxValue; // Setup timer // This is just used for timing during test!! // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock); // 1 second // Create a RFFT instance arm_rfft_fast_instance_f32 fft; arm_rfft_fast_init_f32(&fft,fftSize); // Run FFT // ROM_TimerEnable(TIMER0_BASE, TIMER_A); // startTime = TIMER0_TAR_R; /* Process the real data through the RFFT module */ arm_rfft_fast_f32(&fft, inputData, rfftOutput, ifftFlag); /* Process the data through the Complex Magnitude Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(rfftOutput, testOutput_44khz, fftSize / 2); // The 0 index of FFT output is the DC component of // the input signal. We don't want to consider this when // looking for the peak frequency. testOutput_44khz[0] = 0; /* Calculates maxValue and returns corresponding BIN value */ arm_max_f32(testOutput_44khz, TEST_LENGTH_SAMPLES / 2, &maxValue, &testIndex); // stopTime = TIMER0_TAR_R; // totalTime = startTime - stopTime; // int totalTimeUs = totalTime / 120; //int peakFrequency = testIndex * 22050 / 128; int peakFrequency = testIndex * SAMPLING_RATE / TEST_LENGTH_SAMPLES; MAP_SysCtlDelay(1); }
CCM_FUNC static THD_FUNCTION(ThreadKnock, arg) { (void)arg; chRegSetThreadName("Knock"); q15_t* knockDataPtr; size_t knockDataSize; float32_t maxValue = 0; uint32_t maxIndex = 0; uint16_t i; /* ADC 3 Ch1 Offset. -2048 */ ADC3->OFR1 = ADC_OFR1_OFFSET1_EN | ((1 << 26) & ADC_OFR1_OFFSET1_CH) | (2048 & 0xFFF); dacPutChannelX(&DACD1, 0, 2048); // This sets the offset for the knock ADC opamp. chThdSleepMilliseconds(200); adcStartConversion(&ADCD3, &adcgrpcfg_knock, samples_knock, ADC_GRP2_BUF_DEPTH); /* Initialize the CFFT/CIFFT module */ arm_rfft_fast_instance_f32 S1; arm_rfft_fast_init_f32(&S1, FFT_SIZE); while (TRUE) { while (!recvFreeSamples(&knockMb, (void*)&knockDataPtr, &knockDataSize)) chThdSleepMilliseconds(2); /* Copy and convert ADC samples */ for (i=0; i<FFT_SIZE*2; i+=4) { /* Hann Window */ float32_t multiplier = (1.0 - arm_cos_f32((2.0*PI*(float32_t)i)/(((float32_t)FFT_SIZE*2.0)-1.0))); input[i] = multiplier*(float32_t)knockDataPtr[i]; input[i+1] = multiplier*(float32_t)knockDataPtr[i+1]; input[i+2] = multiplier*(float32_t)knockDataPtr[i+2]; input[i+3] = multiplier*(float32_t)knockDataPtr[i+3]; } /* Process the data through the RFFT module */ arm_rfft_fast_f32(&S1, input, output, 0); /* Process the data through the Complex Magnitude Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(output, mag_knock, FFT_SIZE/2); // Calculate magnitude, outputs q2.14 arm_max_f32(mag_knock, FFT_SIZE/2, &maxValue, &maxIndex); // Find max magnitude // Convert 2.14 to 8 Bits unsigned for (i=0; i < sizeof(output_knock); i++) { uint16_t tmp = (mag_knock[i]/16384); if (tmp > 0xFF) tmp = 0xFF; output_knock[i] = tmp; // 8 bits minus the 2 fractional bits } sensors_data.knock_freq = settings.knockFreq; if (settings.sensorsInput == SENSORS_INPUT_TEST) { sensors_data.knock_value = rand16(0, 255); continue; } sensors_data.knock_value = calculateKnockIntensity( settings.knockFreq, settings.knockRatio, FFT_FREQ, output_knock, sizeof(output_knock)); } return; }
/** Performs one FFT calculation and writes output into a text file. */ static void fft_test_and_output(void) { arm_rfft_fast_init_f32(&rfft, FFT_SIZE); memset(fft_out, 0, sizeof(fft_out)); arm_rfft_fast_f32(&rfft, fft_in, fft_out, 0); fft_write_output(); debug_printf("fft done - output written to file\n"); }
void FFTprocessing2(uint32_t *inFFT, float32_t* outFFT) { uint16_t m; for (m = 0; m < NUM_SAMPLES ; m++) outFFT[m] = (float) inFFT[m]; //- (float) 0x800; // arm_rfft_f32(&fftStructure, outFFT, outFFT); arm_rfft_fast_f32(&FastfftStructure, outFFT, outFFT, ifftFlag); arm_cmplx_mag_f32(outFFT, outFFT, NUM_SAMPLES * 2); // ignore the DC value outFFT[0] = 0.0f; uint16_t n = 0; ///(50*SAMPLE_RATE)/fftLength; // squash everything under 100Hz for (n = 0; n < fix_minFFTIndex; n++) { outFFT[n] = 0.0f; } arm_max_f32(outFFT, NUM_SAMPLES, &fftNode[0].maxValue, &fftNode[0].maxIndex); // calculate frequency value of peak bin fftNode[0].hertz = (fftNode[0].HerztPerBin * (float32_t) fftNode[0].maxIndex) / 2; setAgainSampling(); }