this program will do FFT on an audio signal

Dependencies:   mbed Grove_LCD_RGB_Backlight UIT_FFT_Real

main.cpp

Committer:
SBACCARI
Date:
2019-04-15
Revision:
1:a806f3aacf1f
Parent:
0:c7f159ed0bc3

File content as of revision 1:a806f3aacf1f:

#include "mbed.h"
#include "Grove_LCD_RGB_Backlight.h"
#include "fftReal.hpp"

Grove_LCD_RGB_Backlight ecran(P0_27, P0_28);
AnalogIn micro(A1);
DigitalOut myled(LED1);

Ticker sampler;
const int FFT_len = 256;
int sampling_freq = 44000;
float samples[FFT_len*2];
int i = 0;

void sampling_interrup()
{
    samples[i] = 1024*micro.read(); // 1024 : ADC of the sound sensor
    i++;
    if (i >= FFT_len*2) {
        sampler.detach();
    }
}

void samplingBegin()
{
    // Reset sample buffer position and start callback at the sampling frequency
    i = 0;
    sampler.attach_us(&sampling_interrup, 1000000/sampling_freq);
}

bool samplingDone()
{
    return i >= FFT_len*2;
}


int main() {
    char str[20];
    
    // max 1 is set to the second FFT bin, because the first bin has the DC componenet of the signal.
    int max1 = 2; 
    int max2 = 3;
    float val = 0;
    
    // CONFIG FFT
    Mikami::Complex fft_bins[FFT_len];
    Mikami::FftReal fft((int16_t)FFT_len);

    // CONFIG ECRAN
    ecran.setRGB(0, 255, 0);
    ecran.clear();
    ecran.locate(0, 1);
    
    samplingBegin();
    
    // The following loop, will do FFT and display highest detected frequency on the screen every 2s
    // Commented sections, are debug mode. If uncommented, it will do FFT, display all the  spectrum then restart, it will take about 10s + FFT_len/2 seconds
    
    while(1) {
        /*ecran.clear();
        sprintf(str,"Sampling ...");
        ecran.print(str);
        ecran.setRGB(255, 0, 0);
        wait(0.6);
        ecran.setRGB(0, 0, 255);
        wait(0.6);
        ecran.setRGB(0, 255, 0);*/
        
        // DO FFT
        if (samplingDone())
        {
            /*ecran.locate(0, 0);
            sprintf(str,"Sampling done");
            ecran.print(str);
            wait(1);*/
                
            fft.Execute(samples,fft_bins);
            wait(0.5);
            
            /*ecran.clear();
            sprintf(str,"FFT Done");
            ecran.print(str);
            wait(1);*/
            
            // PRINT SPECTRUM
            for(int j = 0;j < FFT_len/2 ;++j){
                ecran.clear();
                float mod = std::abs(fft_bins[j]);
                float freq = j*sampling_freq/(FFT_len*1000);
                
                /*sprintf(str,"%d.Freq = %.2f kHz", j,freq );
                ecran.locate(0,1);
                ecran.print(str);
                
                sprintf(str,"%d.Mag = %.2f", j, mod );
                ecran.locate(0,0);
                ecran.print(str);*/
                
                if( (j>5)and mod >= std::abs(fft_bins[max1]) ){
                    max1 = j;
                }
                /*else if ( (j>3) and (std::abs(fft_bins[j]) >= std::abs(fft_bins[max2])) and (std::abs(fft_bins[j]) < std::abs(fft_bins[max1]))){
                    max2 = j;
                }
                wait(1);*/
            }
            
            val = max1*sampling_freq/(FFT_len*1000);
            float mod = std::abs(fft_bins[max1]);
            
            /*sprintf(str,"%max1= %.2f", mod );
            ecran.locate(0,0);
            ecran.print(str);*/
            
            ecran.clear();
            sprintf(str,"max= %.2f kHz", val );
            ecran.locate(0,0);
            ecran.print(str);
            wait(2);

            /*val =  max2*sampling_freq/(FFT_len*1000);
            sprintf(str,"max 2 = %.2f kHz", val);
            ecran.locate(0,1);
            ecran.print(str);
            wait(2);*/
                
            samplingBegin();
                
        }
        
        /* // DEBUG SCREEN
        ecran.clear();
        myled = !myled;
        sprintf(str,"Waiting ...");
        ecran.print(str);*/
    }
}