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 Senior Design: Sound Monitor

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