Final version.

Dependencies:   F746_GUI F746_SAI_IO UIT_FFT_Real

Fork of F746_Spectrogram by 不韋 呂

main.cpp

Committer:
mladjo1993
Date:
2017-08-30
Revision:
8:99d57d6e0ea1
Parent:
7:23b60827582d

File content as of revision 8:99d57d6e0ea1:

/********************************************************
 *  Real time spectrogram
 *      Input: MEMS microphone
 *
 *  Mladen Adamovic, 3326/2016
 ********************************************************/

#include "SAI_InOut.hpp"
#include "F746_GUI.hpp"
#include "MethodCollection.hpp"
using namespace etf;

//typedef enum {2D,3D}

int main()
{
    const int FS = AUDIO_FREQUENCY_16K; // Sampling frequency: 16 kHz
    const int N_FFT = 512;              // FFT score
    SaiIO mySai(SaiIO::INPUT, N_FFT+1, FS,          // Use with force
                INPUT_DEVICE_DIGITAL_MICROPHONE_2); // Input device: MEMS microphone

    LCD_DISCO_F746NG &lcd = GuiBase::GetLcd();  // Obtain reference of object of LCD display
    lcd.Clear(GuiBase::ENUM_BACK);
    Label myLabel1(240, 2, "Real-time spectrogram", Label::CENTER, Font16);

    // Set ButtonGroup
    const uint16_t B_W = 50;
    const uint16_t B_Y = 242;
    const uint16_t B_H = 30;
    const string RUN_STOP[3] = {"2D","3D", "STOP"};
    ButtonGroup runStop(275, B_Y, B_W, B_H, 3, RUN_STOP, 0, 0, 3, 2);

    Button clearButton(430, B_Y, B_W, B_H, "CLEAR");
    clearButton.Inactivate();

    // Coordinate axis
    const uint16_t X0 = 40;         // The origin of the x coordinate of the display area
    const uint16_t Y0 = 200;        // The origin of the y coordinate of the display area
    const uint16_t PX_1KHZ = 32;    // Number of pixels corresponding to 1 kHz - 3D view
    const uint16_t PX_20dB = 20;    // Number of pixels corresponding to 20 dB - 2D view
    const uint16_t H0 = PX_1KHZ*5;  // Number of pixels corresponding to the length of the frequency axis (corresponding to 5 kHz)
    const uint16_t W0_3D = 360;        // Width in the horizontal direction 3D (unit: pixels)
    const uint16_t W0_2D = 384;        // Width in the horizontal direction 2D (unit: pixels)
    const float FRAME = (N_FFT/(float)FS)*1000.0f;  // Time corresponding to one frame (unit: ms)
    const uint16_t H_BAR = 2;       // The number of pixels in the horizontal direction corresponding to one frame when displaying
    const uint16_t MS100 = 100*H_BAR/FRAME; // Number of pixels corresponding to 100 ms 3D
    const float Hz100 = 6.4;                // Number of pixels corresponding to 100 hz 2D
    const uint32_t AXIS_COLOR = LCD_COLOR_WHITE;    
    DrawAxis2D(X0, Y0, W0_2D, H0, AXIS_COLOR, Hz100, PX_20dB, lcd);

    Array<float> sn(N_FFT+1);   // Buffer for storing signals for spectrum analysis
    Array<float> db(N_FFT/2+1); // A buffer storing the calculated log spectrum
    // Two-dimensional array that stores color data corresponding to the size of spectrum
    Matrix<uint32_t> spectra(W0_3D/H_BAR, H0+1, GuiBase::ENUM_BACK);
    FftAnalyzer fftAnalyzer(N_FFT+1, N_FFT);

    // Initialization of variable used in loop
    int stop = 0;       // 0: run, 1: stop
    int screen = 0;     // 0: 2D,  1: 3D

    while(!runStop.Touched(0) && !runStop.Touched(1)) {}   // Wait till you touch "2D" or "3D"
    // Start reading data
    mySai.RecordIn();
    while(!mySai.IsCaptured()) {}

    while (true)
    {
        runStop.GetTouchedNumber(stop);
        switch(stop){
        case 0:
            clearButton.Inactivate();
            if (screen == 1)
            {
                // Clear relationship between color and dB
                ClearColorDb(Y0, AXIS_COLOR, lcd);
                // Draw 2D axis
                DrawAxis2D(X0, Y0, W0_2D, H0, AXIS_COLOR, Hz100, PX_20dB, lcd);
                // Screen - 2D
                screen = 0;
            }
            if (mySai.IsCaptured())
            {
                // Input of signal for one frame
                for (int n=0; n<mySai.GetLength(); n++)
                {
                    int16_t xL, xR;
                    mySai.Input(xL, xR);
                    sn[n] = (float)xL;
                }
                // Spectrum update
                SpectrumUpdate(spectra, fftAnalyzer, sn, db);
                // Display 2D spectrum
                DisplaySpectrum2D(db, X0, Y0, W0_2D/H_BAR, H_BAR, lcd);
            }
            break;
        case 1:
            clearButton.Inactivate();
            if (screen == 0)
            {
                // Draw relationship between color and dB
                DrawColorDb(Y0, AXIS_COLOR, lcd);
                // Draw 3D axis
                DrawAxis3D(X0, Y0, W0_3D, H0, AXIS_COLOR, MS100, PX_1KHZ, lcd);
                // Screen - 3D
                screen = 1;
            }
            if (mySai.IsCaptured())
            {
                // Input of signal for one frame
                for (int n=0; n<mySai.GetLength(); n++)
                {
                    int16_t xL, xR;
                    mySai.Input(xL, xR);
                    sn[n] = (float)xL;
                }
                // Spectrum update
                SpectrumUpdate(spectra, fftAnalyzer, sn, db);
                // Display spectrum
                DisplaySpectrum3D(spectra, X0, Y0, H_BAR, lcd);
              }
              break;
        case 2:
            clearButton.Activate();
            if (clearButton.Touched())
            {
                if (screen == 1)
                {
                    spectra.Fill(GuiBase::ENUM_BACK);   // Process for clearing the spectrum display
                    DisplaySpectrum3D(spectra, X0, Y0, H_BAR, lcd);   // Clear spectrum display
                }
                else
                    ClearDisplay(X0, Y0, W0_2D, H0+1, lcd);
                clearButton.Draw();
            }
            break;
        }
    }
}