AudioRecord and FFT/MSE comparison. Call AudioRecord_demo for control record and AudioSample for subsequent recordings.
Dependencies: CMSIS_DSP_401 STM32L4xx_HAL_Driver
Fork of OneHopeOnePrayer by
audio_record.c
- Committer:
- EricLew
- Date:
- 2015-12-05
- Revision:
- 5:f6afbd3fc47a
- Parent:
- 4:652cb54276d0
File content as of revision 5:f6afbd3fc47a:
//EXTERNAL FUNCTIONS/VARIABLES: //AudioRecord_demo //AudioSample //PWRCONTROLMSE //PHSCONTROLMSE //CONTROLPWR0 //CONTROLPHASE0 //DISPLAYFFT #include "main.h" //GLOBAL VARIABLES int EXIT=0; //WHILE LOOP EXIT FLAG float32_t compare[1024]; //BUFFER VARIABLE FOR MSE FUNCTIONS uint32_t counter=0; //COUNTER for lenthg of record uint32_t n; //Generic variable for "for" loops float32_t PWRCONTROLMSE=0; //CONTROL POWER MSE float32_t PHSCONTROLMSE=0; //CONTROL PHASE MSE float32_t CONTROLPWR0[1024]; //CONTROL RECRODING 0 MAGNITUDE float32_t CONTROLPHASE0[1024];//CONTROL RECORDING 0 PHASE float32_t DISPLAYFFT[1024]; const static arm_cfft_instance_f32 *S=&arm_cfft_sR_f32_len2048; void AudioRecord_demo(void) { static uint16_t RecordBuffer[2048]; //RECORDING BUFFER FOR Control #0 static uint16_t RecordBuffer1[2048];//RECORDING BUFFER FOR Control #1 float32_t FloatBuff0[2048]; //Casting Int array to float array float32_t FloatBuff1[2048]; float32_t CONTROLPWR1[1024]; //CONTROL RECRODING 1 MAGNITUDE float32_t CONTROLPHASE1[1024];//CONTROL RECORDING 1 PHASE float32_t CONTROLREAL0[1024]; //CONTROL RECORDING 0 REAL float32_t CONTROLIMAG0[1024]; //CONTROL RECORDING 0 IMAGINARY float32_t CONTROLREAL1[1024]; //CONTROL RECORDING 1 REAL float32_t CONTROLIMAG1[1024]; //CONTROL REOCRDING 1 REAL float32_t FloatBuffout0[4096];//CONTROL RECORDING WITH ZEROS ADDED FOR COMPLEX PORTIONS float32_t FloatBuffout1[4096]; //INITIALIZE RECORDING #0 /* Initialize audio input */ BSP_AUDIO_IN_Init(48000, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR); /* Start the audio record */ BSP_AUDIO_IN_Record(&RecordBuffer[0], 2048); /* PCM samples recording loop */ while (EXIT != SET) { if (counter==10000000) //Approximately 3 seconds of record time { EXIT=1; } else { counter=counter++; } } /* Stop audio input */ BSP_AUDIO_IN_Stop(); BSP_AUDIO_IN_Record(&RecordBuffer1[0], 2048); EXIT = 0; //RESET AUDIO RECORD FLAG counter=0; //RESET COUNTER /* PCM samples recording loop */ //COPIED FROM ABOVE USE '1' WHEN REFERENCING VARIABLES while (EXIT != SET) { if (counter==10000000) //Approximately 3 seconds of record time { EXIT=1; //FLAG IS REGISTER R5 } else { counter=counter++; } } /* Stop audio input */ BSP_AUDIO_IN_Stop(); /* De-initialize audio input */ BSP_AUDIO_IN_DeInit(); //END OF RECORDING #1 /* Reset EXIT flag */ EXIT = 0; //CASTS THE RECORD BUFFER AS A SINGLE FLOAT //RECORDING 0 for (n=0; n<2048; n++) {FloatBuff0[n]=(float)RecordBuffer[n];} //RECORDING 1 for (n=0; n<2048; n++) {FloatBuff1[n]=(float)RecordBuffer1[n];} for(n=0;n<2048;n++) {FloatBuffout0[n*2] = FloatBuff0[n]; FloatBuffout0[(n*2)+1] = 0.0; FloatBuffout1[n*2] = FloatBuff1[n]; FloatBuffout1[(n*2)+1] = 0.0;} //PERFORMS THE FFT //RECORDING 0 arm_cfft_f32(S, FloatBuffout0, 0,0); //Output of FFT is half the record buffer size //RECORDING 1 arm_cfft_f32(S, FloatBuffout1, 0,0); //FloatBuffout0[0]=0; //FloatBuffout1[0]=0; // //RECORDING 0 for(n=0;n<2048;n=n+2) {CONTROLREAL0[n]=FloatBuffout0[n];}//Parses Real parts from the buffer for(n=1;n<2048;n=n+2) {CONTROLIMAG0[n]=FloatBuffout0[n];}//Parses Imaginary parts from the buffer //RECORDING 1 for(n=0;n<2048;n=n+2) {CONTROLREAL1[n]=FloatBuffout1[n];}//Parses Real parts from the buffer for(n=1;n<2048;n=n+2) {CONTROLIMAG1[n]=FloatBuffout1[n];}//Parses Imaginary parts from the buffer //CALCULATES PHASE AND MAGITUDE //RECORDING 0 for(n=0;n<1024;n++) {CONTROLPHASE0[n]=atan2(CONTROLIMAG0[n],CONTROLREAL0[n]);}//Calculates control phase for(n=0;n<1024;n++) {CONTROLPWR0[n]=sqrt((CONTROLIMAG0[n]*CONTROLIMAG0[n])+(CONTROLREAL0[n]*CONTROLREAL0[n]));} //calculates control power //RECORDING 1 for(n=0;n<1024;n++) {CONTROLPHASE1[n]=atan2(CONTROLIMAG1[n],CONTROLREAL1[n]);}//Calculates control phase for(n=0;n<1024;n++) {CONTROLPWR1[n]=sqrt((CONTROLIMAG1[n]*CONTROLIMAG1[n])+(CONTROLREAL1[n]*CONTROLREAL1[n]));} //calculates control power //MEAN SQUARED ERROR FOR CONTROL MAGNITUDES for(n=0;n<1024;n++) {compare[n]=CONTROLPWR0[n]-CONTROLPWR1[n];} //Error between FFT magnitudes, stored in compare for(n=0;n<1024;n++) {compare[n]=(compare[n]*compare[n]);} //Squares the error, stores back in compare for(n=0;n<1024;n++) {PWRCONTROLMSE=PWRCONTROLMSE+compare[n];} //Takes the mean of the error, stores MSE in CONTROLMSE PWRCONTROLMSE=PWRCONTROLMSE/1024.0f; //MEAN SQUARED ERROR FOR CONTROL PHASE for(n=0;n<1024;n++) {compare[n]=CONTROLPHASE0[n]-CONTROLPHASE1[n];} //Error between FFT magnitudes, stored in compare for(n=0;n<1024;n++) {compare[n]=(compare[n]*compare[n]);} //Squares the error, stores back in compare for(n=0;n<1024;n++) {PHSCONTROLMSE=PHSCONTROLMSE+compare[n];} //Takes the mean of the error, stores MSE in CONTROLMSE PHSCONTROLMSE=PHSCONTROLMSE/1024.0f; } void AudioSample(void) { //SAMPLE VARIABLES static uint16_t SampleBuffer[2048]; //SAMPLE RECORDING float32_t FloatBuffSAMPLE[2048]; //Casting Int array to float array float32_t SAMPLEPWR[1024]; //SAMPLE RECRODING 1 MAGNITUDE float32_t SAMPLEPHASE[1024];//SAMPLE RECORDING 1 PHASE float32_t SAMPLEREAL[1024]; //SAMPLE RECORDING 0 REAL float32_t SAMPLEIMAG[1024]; //SAMPLE RECORDING 0 IMAGINARY float32_t SAMPLEPWRMSE=0; //MSE float32_t SAMPLEPHASEMSE=0; //MSE //INITIALIZE RECORDING BSP_AUDIO_IN_Init(48000, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR); BSP_AUDIO_IN_Record(&SampleBuffer[0], 2048); EXIT = 0; //RESET AUDIO RECORD FLAG counter=0; //RESET COUNTER /* PCM samples recording loop */ //COPIED FROM ABOVE USE '1' WHEN REFERENCING VARIABLES while (EXIT != SET) { if (counter==10000000) //Approximately 3 seconds of record time { EXIT=1; //FLAG IS REGISTER R5 } else { counter=counter++; } } /* Stop audio input */ BSP_AUDIO_IN_Stop(); /* De-initialize audio input */ BSP_AUDIO_IN_DeInit(); //END OF RECORDING //CASTS THE RECORDING BUFFER AS A FLOAT for (n=0; n<2048; n++) {FloatBuffSAMPLE[n]=(float)SampleBuffer[n];} float32_t FloatBuffSAMPLEout[4096]; for(n=0;n<2048;n++) {FloatBuffSAMPLEout[n*2] = FloatBuffSAMPLE[n]; FloatBuffSAMPLEout[(n*2)+1] = 0.0;} //PERFORMS THE arm_cfft_f32(S, FloatBuffSAMPLEout, 0,0); //Output of FFT is half the record buffer size //FloatBuffSAMPLEout[0]=0; //MSE FUNCTION //SEPARATES REAL AND IMAGINARY PARTS for(n=0;n<2048;n=n+2) {SAMPLEREAL[n]=FloatBuffSAMPLEout[n];}//Parses Real parts from the buffer for(n=1;n<2048;n=n+2) {SAMPLEIMAG[n]=FloatBuffSAMPLEout[n];}//Parses Imaginary parts from the buffer //CALCULATES PHASE AND MAGITUDE //SAMPLE RECORDING for(n=0;n<1024;n++) {SAMPLEPHASE[n]=atan2(SAMPLEIMAG[n],SAMPLEREAL[n]);}//Calculates control phase for(n=0;n<1024;n++) {SAMPLEPWR[n]=sqrt((SAMPLEIMAG[n]*SAMPLEIMAG[n])+(SAMPLEREAL[n]*SAMPLEREAL[n]));} //calculates control power //ASSIGNS SAMPLE MAGNITUDE TO DISPLAY EXTERNAL FOR GRAPHING for(n=0;n<1024;n++) {DISPLAYFFT[n]=SAMPLEPWR[n];} //MEAN SQUARED ERROR FOR SAMPLE MAGNITUDES SAMPLEPWRMSE=0; for(n=0;n<1024;n++) {compare[n]=CONTROLPWR0[n]-SAMPLEPWR[n];} //Error between FFT magnitudes, stored in compare for(n=0;n<1024;n++) {compare[n]=(compare[n]*compare[n]);} //Squares the error, stores back in compare for(n=0;n<1024;n++) {SAMPLEPWRMSE=SAMPLEPWRMSE+compare[n];} //Takes the mean of the error, stores MSE in CONTROLMSE SAMPLEPWRMSE=SAMPLEPWRMSE/1024.0f; //MEAN SQUARED ERROR FOR SAMPLE PHASE SAMPLEPHASEMSE=0; for(n=0;n<1024;n++) {compare[n]=CONTROLPHASE0[n]-SAMPLEPHASE[n];} //Error between FFT magnitudes, stored in compare for(n=0;n<1024;n++) {compare[n]=(compare[n]*compare[n]);} //Squares the error, stores back in compare for(n=0;n<1024;n++) {SAMPLEPHASEMSE=SAMPLEPHASEMSE+compare[n];} //Takes the mean of the error, stores MSE in CONTROLMSE SAMPLEPHASEMSE=SAMPLEPHASEMSE/1024.0f; float32_t TEST[6]; TEST[0]=PWRCONTROLMSE; TEST[1]=PHSCONTROLMSE; TEST[2]=SAMPLEPHASEMSE; TEST[3]=SAMPLEPWRMSE; TEST[4]=(SAMPLEPWRMSE/PWRCONTROLMSE); //The ratio of sample MSE and control MSE TEST[5]=(SAMPLEPHASEMSE/PHSCONTROLMSE); float32_t low=.001; //LOW END OF ACCEPTED TOLERANCE RANGE float32_t high=20; //HIGH END OF ACCEPTED TOLERANCE RANGE //COMPARISON //if(SAMPLEPHASEMSE>(10*PHSCONTROLMSE)) //{ //SEND ERROR MESSAGE //CREATE EVENT //} if(TEST[4]>high)//MODEM FUNCTIONS { //SEND ERROR MESSAGE //CREATE EVENT } if(TEST[4] < low) { //SEND ERROR MESSAGE //CREATE EVENT } }