void fft(){ uint32_t i; arm_cfft_radix4_instance_f32 S; /* ARM CFFT module */ float32_t maxValue; /* Max FFT value is stored here */ uint32_t maxIndex; /* Index in Output array where max value is */ uint32_t height; for(i = 0; i < SIZE; i+=2) { INPUT[i] = ((samples[i]+CAP_FACTOR)/((float32_t) MAX_VALUE/2) - 1); INPUT[i+1] = 0; } /* Initialize the CFFT/CIFFT module, intFlag = 0, doBitReverse = 1 */ arm_cfft_radix4_init_f32(&S, SIZE/2, 0, 1); /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, INPUT); /* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(INPUT, Output, SIZE/2); /* Calculates maxValue and returns corresponding value */ arm_max_f32(Output, SIZE, &maxValue, &maxIndex); if(maxIndex>SIZE/4){ maxIndex=SIZE/2-maxIndex; //Dla lustrzanych } BSP_LCD_Clear(LCD_COLOR_WHITE); /* Display data on LCD */ for (i = 0; i < SIZE; i++) { /* Draw FFT results */ height = (uint16_t)(((float32_t)Output[i] / (float32_t)maxValue) * 180); BSP_LCD_DrawLine(0, 30+i, height, 30+i); } char str[16]; sprintf(str,"%d",(uint32_t)((float32_t)maxIndex*FREQ_FACTOR)); //Model matematyczny BSP_LCD_DisplayStringAtLine(1,(uint8_t *) str); }
void fft_gen(void){ //TODO:バッファをstaticにして関数切り出し.割り込みから呼ぶ,切り出し先はfft.c arm_cfft_radix4_instance_f32 S; /* ARM CFFT module */ float32_t Input[FFT_SAMPLES]; uint32_t maxIndex; /* Index in Output array where max value is */ //ジェネレータのバッファを埋める(ジェネレータ入力時の不足データを繰り返しで埋める)(TODO:ADとgenを振り分け) uint16_t i; int j; j = 0; for (i=buf.numLUTEntries; i < FFT_SIZE; i++) { buf.LUT_BUFFER[i] = buf.LUT_BUFFER[j]; if(j==buf.numLUTEntries-1) { j=0; }else{ j++; } } /* Initialize the CFFT/CIFFT module, intFlag = 0, doBitReverse = 1 */ arm_cfft_radix4_init_f32(&S, FFT_SIZE, 0, 1); for (i = 0; i < FFT_SAMPLES; i += 2) { Input[(uint16_t)i] = (float32_t)((float32_t)buf.LUT_BUFFER[i/2] - (float32_t)2048.0) / (float32_t)2048.0; Input[(uint16_t)(i + 1)] = 0; } /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, Input); /* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(Input, Output, FFT_SIZE); /* Calculates maxValue and returns corresponding value */ arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); //DA=30000sps/4096bit=7.32421875Hzステップでデータが格納されている }
int32_t main(void) { arm_status status; float32_t maxValue; status = ARM_MATH_SUCCESS; /* Process the data through the CFFT/CIFFT module */ arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse); /* Process the data through the Complex Magnitude Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize); /* Calculates maxValue and returns corresponding BIN value */ arm_max_f32(testOutput, fftSize, &maxValue, &testIndex); if(testIndex != refIndex) { status = ARM_MATH_TEST_FAILURE; } /* ---------------------------------------------------------------------- ** Loop here if the signals fail the PASS check. ** This denotes a test failure ** ------------------------------------------------------------------- */ if( status != ARM_MATH_SUCCESS) { while(1); } while(1); /* main function does not return */ }
void FFTprocessing1(uint32_t *inFFT, float32_t* outFFT, FFT_LENGTH_ FFTlength) { if (g_ucDMAMethod == DMA_METHOD_SLOW) { adcNode[0].g_ucDataReady = 0; } float32_t complexBuffer[NUM_SAMPLES ]; ComplexBufFFT(inFFT, complexBuffer, FFTlength); arm_cfft_f32(&arm_cfft_sR_f32_len256, complexBuffer, ifftFlag, doBitReverse); //da test voi 512 nhung chay mot luc thi gia tri khong cap nhat nua arm_cmplx_mag_f32(complexBuffer, outFFT, FFTlength); // 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, FFTlength / 2, &fftNode[0].maxValue, &fftNode[0].maxIndex); arm_mean_f32(outFFT, FFTlength, &fftNode[0].averageValue); // calculate frequency value of peak bin fftNode[0].hertz = fftNode[0].HerztPerBin * (float32_t) fftNode[0].maxIndex * 2; setAgainSampling(); }
/***************************************************************************//** * @brief * Process the sampled audio data through FFT. *******************************************************************************/ void processFFT(void) { uint16_t *inBuf; int32_t right; int32_t left; int i; guitarMonProcessCount++; inBuf = audioToFFTBuffer; /* * Average the left and right channels into one combined floating point buffer */ for (i = 0; i < GUITAR_AUDIO_BUFFER_SAMPLES; ++i) { right = (int32_t) *inBuf++; left = (int32_t) *inBuf++; floatBuf1[i] = (float32_t)( (float32_t)right + (float32_t)left) / 2.0f; } /* Process the data through the RFFT module, resulting complex output is * stored in fftOutputComplex */ arm_rfft_f32(&rfft_instance, floatBuf1, fftOutputComplex); /* Compute the magnitude of all the resulting complex numbers */ arm_cmplx_mag_f32(fftOutputComplex, fftOutputMag, GUITAR_AUDIO_BUFFER_SAMPLES); }
void DSPCalculateFFT(tDSPInstance* instance) { if (instance->signalSize != 1024*8) { UART_PRINT("signalsize different than expected!\n\r"); while(1) {}//signal size different than our assumption } uint32_t ifftFlag = 0; uint32_t doBitReverse = 1; uint32_t i; // UART_PRINT("\n\r\n\r"); // for (i=0; i<instance->signalSize; i++) { // UART_PRINT("%d ", instance->ucpSignal[i]); // } // UART_PRINT("\n\r\n\r"); // UART_PRINT("\n\r\n\r"); // for (i=0; i<instance->signalSize/2; i++) { // UART_PRINT("%f ", instance->fpSignal[i]); // } // UART_PRINT("\n\r\n\r"); /* Hanning window the time signal */ for (i=0; i<instance->signalSize/2; i++) { instance->fpSignal[i] *= HanningWindow_4096[i]; } // UART_PRINT("\n\r\n\r"); // for (i=0; i<instance->signalSize/2; i++) { // UART_PRINT("%f ", instance->fpSignal[i]); // } // UART_PRINT("\n\r\n\r"); /* Process the data through the CFFT/CIFFT module */ arm_cfft_f32(&arm_cfft_sR_f32_len2048, instance->fpSignal, ifftFlag, doBitReverse); // UART_PRINT("\n\r\n\r"); // for (i=0; i<instance->signalSize/2; i++) { // UART_PRINT("%f ", instance->fpSignal[i]); // } // UART_PRINT("\n\r\n\r"); /* Process the data through the Complex Magnitude Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(instance->fpSignal, instance->FFTResults, instance->fftSize); //ignore dc bias instance->FFTResults[0] = 0; //also ignore 2nd bin when using hanning window (got this from experimentation) instance->FFTResults[1] = 0; // UART_PRINT("\n\r\n\r"); // for (i=0; i<instance->fftSize; i++) { // UART_PRINT("%f ", instance->FFTResults[i]); // } // UART_PRINT("\n\r\n\r"); /* Calculates maxValue and returns corresponding BIN value */ arm_max_f32(instance->FFTResults, instance->fftSize/2/*only half of fft is unique*/, &instance->maxEnergyBinValue, &instance->maxEnergyBinIndex); // UART_PRINT("max energy at (%d:%f)\n\r", instance->maxEnergyBinIndex, instance->maxEnergyBinValue); // UART_PRINT("\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r"); }
float ComplexFloatArray::mag(const int i){ float result; #ifdef ARM_CORTEX arm_cmplx_mag_f32((float*)&(data[i]), &result,1); #else result=sqrtf(mag2(i)); #endif return result; }
void ComplexFloatArray::getMagnitudeValues(FloatArray& dest){ #ifdef ARM_CORTEX arm_cmplx_mag_f32((float*)data, (float*)dest, size); #else for(int i=0; i<size; i++){ dest[i]=mag(i); } #endif }
int32_t main(void) { volatile int32_t iCount; arm_status status; arm_cfft_radix4_instance_f32 S; float32_t maxValue; STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED6); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED6); status = ARM_MATH_SUCCESS; /* Initialize the CFFT/CIFFT module */ status = arm_cfft_radix4_init_f32(&S, fftSize, ifftFlag, doBitReverse); /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, testInput_f32_10khz); /* Process the data through the Complex Magnitude Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize); /* Calculates maxValue and returns corresponding BIN value */ arm_max_f32(testOutput, fftSize, &maxValue, &testIndex); if(testIndex != refIndex) { status = ARM_MATH_TEST_FAILURE; STM_EVAL_LEDOn(LED3); } /* ---------------------------------------------------------------------- ** Loop here if the signals fail the PASS check. ** This denotes a test failure ** ------------------------------------------------------------------- */ if( status != ARM_MATH_SUCCESS) { while(1); } while(1) { STM_EVAL_LEDOn(LED6); for (iCount = 0; iCount < 1000000; iCount++); STM_EVAL_LEDOff(LED6); for (iCount = 0; iCount < 1000000; iCount++); } }
void TM_FFT_Process_F32(TM_FFT_F32_t* FFT) { /* Process FFT */ arm_cfft_f32(FFT->S, FFT->Input, 0, 1); /* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(FFT->Input, FFT->Output, FFT->FFT_Size); /* Calculates maxValue and returns corresponding value */ arm_max_f32(FFT->Output, FFT->FFT_Size, &FFT->MaxValue, &FFT->MaxIndex); /* Reset count */ FFT->Count = 0; }
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); }
void fft_adc(void){ uint16_t i; //TODO:バッファをstaticにして関数切り出し.割り込みから呼ぶ,切り出し先はfft.c arm_cfft_radix4_instance_f32 S; /* ARM CFFT module */ float32_t Input[FFT_SAMPLES]; uint32_t maxIndex; /* Index in Output array where max value is */ /* Initialize the CFFT/CIFFT module, intFlag = 0, doBitReverse = 1 */ arm_cfft_radix4_init_f32(&S, FFT_SIZE, 0, 1); for (i = 0; i < FFT_SAMPLES; i += 2) { Input[(uint16_t)i] = (float32_t)((float32_t)adc_buf[i/2] - (float32_t)2048.0) / (float32_t)2048.0; Input[(uint16_t)(i + 1)] = 0; } /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, Input); /* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(Input, Output, FFT_SIZE); /* Calculates maxValue and returns corresponding value */ arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); //AD=79872sps/4096bit=19.5Hzステップでデータが格納される }
void main (void) { /*开硬件浮点*/ SCB->CPACR |=((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ uint16 flag; uint16 i,j; DisableInterrupts; LCD_init(1); Disp_single_colour(Black); LCD_PutString(10, 50,"Frequency: ", White, Black); LCD_PutString(145, 50," KHz", White, Black); LCD_PutString(10, 80,"Power: ", White, Black); LCD_PutString(145, 80," W", White, Black); LCD_PutString(10, 110,"Amplify: ", White, Black); LCD_PutString(165, 110,"Restrain: ", White, Black); init_ADC(); init_DAC(); init_DMA(); init_PDB(); init_PIT(); init_gpio_PE24(); EnableInterrupts; LPLD_LPTMR_DelayMs(100); flag = Result_flag; uint16 ShowAFlag = 0; uint16 ShowBFlag = 0; uint16 ShowCFlag = 0; arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32[0], &firStateF32[0], blockSize); while(1) { if( flag==Result_flag && Result_flag == 0) { if(++ShowAFlag<10) { for(j = 0;j<LENGTH;j++) testInput_x[j*2] = Result_A[j]; for(j = 0;j<LENGTH;j++) testInput_x[j*2+1] = 0; arm_cfft_f32(&arm_cfft_sR_f32_len2048, testInput_x, ifftFlag, doBitReverse); /* Process the data through the Complex Magnitude Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(testInput_x, testOutput, fftSize); testOutput[0] = 0; /* Calculates maxValue and returns corresponding BIN value */ arm_max_f32(testOutput, fftSize, &maxValue, &testIndex); } else { ShowAFlag = 0; if(starfir !=2 ) LCD_Put_Float(100, 50,"",testIndex*40.0/2048, White, Black); } if(starfir == 1) { PTE24_O = 1; for(j = 0;j<LENGTH;j++) firInput[j] = Result_A[j]; inputF32 = &firInput[0]; outputF32 = &firOutput[0]; for(i=0; i < numBlocks; i++) arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize); for(j = 0;j<LENGTH;j++) Result_A[j] = firOutput[j]; PTE24_O = 0; } flag = 1; } else if(flag==Result_flag && Result_flag == 1) { if(starfir !=2 ) { if(++ShowBFlag<10) { power = 0; for(i=0;i<LENGTH;i++) power+=((Result_B[i] - OFFEST)/1241.0)*((Result_B[i] - OFFEST)/1241.0)*90*MyDb/8.0; power = power/LENGTH; } else { ShowBFlag = 0; LCD_Put_Float(100, 80,"",power, White, Black); } } else { for(i = 0;i<160;i++) { FFT_RESULT_NEW[i] = testOutput[i*6]/FFT_VALUE; if(FFT_RESULT_NEW[i]>239) FFT_RESULT_NEW[i] = 239; } } // { // for(j = 0;j<LENGTH;j++) // testInput_x[j*2] = Result_B[j]; // for(j = 0;j<LENGTH;j++) // testInput_x[j*2+1] = 0; // // arm_cfft_f32(&arm_cfft_sR_f32_len2048, testInput_x, ifftFlag, doBitReverse); // // /* Process the data through the Complex Magnitude Module for // calculating the magnitude at each bin */ // arm_cmplx_mag_f32(testInput_x, testOutput, fftSize); // // testOutput[0] = 0; // /* Calculates maxValue and returns corresponding BIN value */ // arm_max_f32(testOutput, fftSize, &maxValue, &testIndex); // } if(starfir == 1) { PTE24_O = 1; for(j = 0;j<LENGTH;j++) firInput[j] = Result_B[j]; inputF32 = &firInput[0]; outputF32 = &firOutput[0]; for(i=0; i < numBlocks; i++) arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize); for(j = 0;j<LENGTH;j++) Result_B[j] = firOutput[j]; PTE24_O = 0; } flag = 2; } else if(flag==Result_flag && Result_flag == 2) { // // { // for(j = 0;j<LENGTH;j++) // testInput_x[j*2] = Result_C[j]; // for(j = 0;j<LENGTH;j++) // testInput_x[j*2+1] = 0; // // arm_cfft_f32(&arm_cfft_sR_f32_len2048, testInput_x, ifftFlag, doBitReverse); // // /* Process the data through the Complex Magnitude Module for // calculating the magnitude at each bin */ // arm_cmplx_mag_f32(testInput_x, testOutput, fftSize); // // testOutput[0] = 0; // /* Calculates maxValue and returns corresponding BIN value */ // arm_max_f32(testOutput, fftSize, &maxValue, &testIndex); // } if(starfir == 1) { // PTE24_O = 1; for(j = 0;j<LENGTH;j++) firInput[j] = Result_C[j]; inputF32 = &firInput[0]; outputF32 = &firOutput[0]; for(i=0; i < numBlocks; i++) arm_fir_f32(&S, inputF32 + (i * blockSize), outputF32 + (i * blockSize), blockSize); for(j = 0;j<LENGTH;j++) Result_C[j] = firOutput[j]; // PTE24_O = 0; } if(starfir != 2) { if(++ShowCFlag<5) { } else { if(ShowMenu) { Disp_single_colour(Black); LCD_PutString(10, 50,"Frequency: ", White, Black); LCD_PutString(145, 50," KHz", White, Black); LCD_PutString(10, 80,"Power: ", White, Black); LCD_PutString(145, 80," W", White, Black); LCD_PutString(10, 110,"Amplify: ", White, Black); LCD_PutString(165, 110,"Restrain: ", White, Black); ShowMenu = 0; } LCD_Put_Float(100, 110,"",MyDb/0.5, White, Black); if(starfir) LCD_PutString(260, 110,"On ", White, Black); else LCD_PutString(260, 110,"Off", White, Black); } } else { if(ShowMenu) { Disp_single_colour(Black); ShowMenu = 0; } draw_fft(); } flag = 0; } } }
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; }
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(); }