Final version.
Dependencies: F746_GUI F746_SAI_IO UIT_FFT_Real
Fork of F746_Spectrogram by
main.cpp@9:444e58089d09, 2017-08-30 (annotated)
- Committer:
- mladjo1993
- Date:
- Wed Aug 30 07:47:58 2017 +0000
- Revision:
- 9:444e58089d09
- Parent:
- 8:99d57d6e0ea1
Final version.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mladjo1993 | 7:23b60827582d | 1 | /******************************************************** |
mladjo1993 | 7:23b60827582d | 2 | * Real time spectrogram |
mladjo1993 | 7:23b60827582d | 3 | * Input: MEMS microphone |
mladjo1993 | 7:23b60827582d | 4 | * |
mladjo1993 | 7:23b60827582d | 5 | * Mladen Adamovic, 3326/2016 |
mladjo1993 | 7:23b60827582d | 6 | ********************************************************/ |
MikamiUitOpen | 0:9470a174c910 | 7 | |
MikamiUitOpen | 0:9470a174c910 | 8 | #include "SAI_InOut.hpp" |
MikamiUitOpen | 2:1f092ac020e1 | 9 | #include "F746_GUI.hpp" |
MikamiUitOpen | 0:9470a174c910 | 10 | #include "MethodCollection.hpp" |
mladjo1993 | 8:99d57d6e0ea1 | 11 | using namespace etf; |
mladjo1993 | 8:99d57d6e0ea1 | 12 | |
mladjo1993 | 8:99d57d6e0ea1 | 13 | //typedef enum {2D,3D} |
MikamiUitOpen | 0:9470a174c910 | 14 | |
MikamiUitOpen | 0:9470a174c910 | 15 | int main() |
MikamiUitOpen | 0:9470a174c910 | 16 | { |
mladjo1993 | 7:23b60827582d | 17 | const int FS = AUDIO_FREQUENCY_16K; // Sampling frequency: 16 kHz |
mladjo1993 | 7:23b60827582d | 18 | const int N_FFT = 512; // FFT score |
mladjo1993 | 7:23b60827582d | 19 | SaiIO mySai(SaiIO::INPUT, N_FFT+1, FS, // Use with force |
mladjo1993 | 7:23b60827582d | 20 | INPUT_DEVICE_DIGITAL_MICROPHONE_2); // Input device: MEMS microphone |
MikamiUitOpen | 0:9470a174c910 | 21 | |
mladjo1993 | 7:23b60827582d | 22 | LCD_DISCO_F746NG &lcd = GuiBase::GetLcd(); // Obtain reference of object of LCD display |
MikamiUitOpen | 5:c0877670b0ac | 23 | lcd.Clear(GuiBase::ENUM_BACK); |
MikamiUitOpen | 2:1f092ac020e1 | 24 | Label myLabel1(240, 2, "Real-time spectrogram", Label::CENTER, Font16); |
MikamiUitOpen | 0:9470a174c910 | 25 | |
mladjo1993 | 7:23b60827582d | 26 | // Set ButtonGroup |
MikamiUitOpen | 0:9470a174c910 | 27 | const uint16_t B_W = 50; |
MikamiUitOpen | 0:9470a174c910 | 28 | const uint16_t B_Y = 242; |
MikamiUitOpen | 0:9470a174c910 | 29 | const uint16_t B_H = 30; |
mladjo1993 | 8:99d57d6e0ea1 | 30 | const string RUN_STOP[3] = {"2D","3D", "STOP"}; |
mladjo1993 | 8:99d57d6e0ea1 | 31 | ButtonGroup runStop(275, B_Y, B_W, B_H, 3, RUN_STOP, 0, 0, 3, 2); |
MikamiUitOpen | 6:b3885567877c | 32 | |
MikamiUitOpen | 6:b3885567877c | 33 | Button clearButton(430, B_Y, B_W, B_H, "CLEAR"); |
MikamiUitOpen | 6:b3885567877c | 34 | clearButton.Inactivate(); |
MikamiUitOpen | 0:9470a174c910 | 35 | |
mladjo1993 | 7:23b60827582d | 36 | // Coordinate axis |
mladjo1993 | 7:23b60827582d | 37 | const uint16_t X0 = 40; // The origin of the x coordinate of the display area |
mladjo1993 | 7:23b60827582d | 38 | const uint16_t Y0 = 200; // The origin of the y coordinate of the display area |
mladjo1993 | 8:99d57d6e0ea1 | 39 | const uint16_t PX_1KHZ = 32; // Number of pixels corresponding to 1 kHz - 3D view |
mladjo1993 | 8:99d57d6e0ea1 | 40 | const uint16_t PX_20dB = 20; // Number of pixels corresponding to 20 dB - 2D view |
mladjo1993 | 7:23b60827582d | 41 | const uint16_t H0 = PX_1KHZ*5; // Number of pixels corresponding to the length of the frequency axis (corresponding to 5 kHz) |
mladjo1993 | 8:99d57d6e0ea1 | 42 | const uint16_t W0_3D = 360; // Width in the horizontal direction 3D (unit: pixels) |
mladjo1993 | 8:99d57d6e0ea1 | 43 | const uint16_t W0_2D = 384; // Width in the horizontal direction 2D (unit: pixels) |
mladjo1993 | 7:23b60827582d | 44 | const float FRAME = (N_FFT/(float)FS)*1000.0f; // Time corresponding to one frame (unit: ms) |
mladjo1993 | 7:23b60827582d | 45 | const uint16_t H_BAR = 2; // The number of pixels in the horizontal direction corresponding to one frame when displaying |
mladjo1993 | 8:99d57d6e0ea1 | 46 | const uint16_t MS100 = 100*H_BAR/FRAME; // Number of pixels corresponding to 100 ms 3D |
mladjo1993 | 8:99d57d6e0ea1 | 47 | const float Hz100 = 6.4; // Number of pixels corresponding to 100 hz 2D |
MikamiUitOpen | 6:b3885567877c | 48 | const uint32_t AXIS_COLOR = LCD_COLOR_WHITE; |
mladjo1993 | 8:99d57d6e0ea1 | 49 | DrawAxis2D(X0, Y0, W0_2D, H0, AXIS_COLOR, Hz100, PX_20dB, lcd); |
MikamiUitOpen | 6:b3885567877c | 50 | |
mladjo1993 | 7:23b60827582d | 51 | Array<float> sn(N_FFT+1); // Buffer for storing signals for spectrum analysis |
mladjo1993 | 7:23b60827582d | 52 | Array<float> db(N_FFT/2+1); // A buffer storing the calculated log spectrum |
mladjo1993 | 7:23b60827582d | 53 | // Two-dimensional array that stores color data corresponding to the size of spectrum |
mladjo1993 | 8:99d57d6e0ea1 | 54 | Matrix<uint32_t> spectra(W0_3D/H_BAR, H0+1, GuiBase::ENUM_BACK); |
MikamiUitOpen | 0:9470a174c910 | 55 | FftAnalyzer fftAnalyzer(N_FFT+1, N_FFT); |
MikamiUitOpen | 0:9470a174c910 | 56 | |
mladjo1993 | 7:23b60827582d | 57 | // Initialization of variable used in loop |
MikamiUitOpen | 6:b3885567877c | 58 | int stop = 0; // 0: run, 1: stop |
mladjo1993 | 8:99d57d6e0ea1 | 59 | int screen = 0; // 0: 2D, 1: 3D |
MikamiUitOpen | 3:6a2c8ff46f73 | 60 | |
mladjo1993 | 8:99d57d6e0ea1 | 61 | while(!runStop.Touched(0) && !runStop.Touched(1)) {} // Wait till you touch "2D" or "3D" |
mladjo1993 | 7:23b60827582d | 62 | // Start reading data |
MikamiUitOpen | 0:9470a174c910 | 63 | mySai.RecordIn(); |
MikamiUitOpen | 6:b3885567877c | 64 | while(!mySai.IsCaptured()) {} |
MikamiUitOpen | 6:b3885567877c | 65 | |
MikamiUitOpen | 0:9470a174c910 | 66 | while (true) |
MikamiUitOpen | 0:9470a174c910 | 67 | { |
MikamiUitOpen | 0:9470a174c910 | 68 | runStop.GetTouchedNumber(stop); |
mladjo1993 | 8:99d57d6e0ea1 | 69 | switch(stop){ |
mladjo1993 | 8:99d57d6e0ea1 | 70 | case 0: |
MikamiUitOpen | 6:b3885567877c | 71 | clearButton.Inactivate(); |
mladjo1993 | 8:99d57d6e0ea1 | 72 | if (screen == 1) |
mladjo1993 | 8:99d57d6e0ea1 | 73 | { |
mladjo1993 | 8:99d57d6e0ea1 | 74 | // Clear relationship between color and dB |
mladjo1993 | 8:99d57d6e0ea1 | 75 | ClearColorDb(Y0, AXIS_COLOR, lcd); |
mladjo1993 | 8:99d57d6e0ea1 | 76 | // Draw 2D axis |
mladjo1993 | 8:99d57d6e0ea1 | 77 | DrawAxis2D(X0, Y0, W0_2D, H0, AXIS_COLOR, Hz100, PX_20dB, lcd); |
mladjo1993 | 8:99d57d6e0ea1 | 78 | // Screen - 2D |
mladjo1993 | 8:99d57d6e0ea1 | 79 | screen = 0; |
mladjo1993 | 8:99d57d6e0ea1 | 80 | } |
MikamiUitOpen | 0:9470a174c910 | 81 | if (mySai.IsCaptured()) |
MikamiUitOpen | 0:9470a174c910 | 82 | { |
mladjo1993 | 7:23b60827582d | 83 | // Input of signal for one frame |
MikamiUitOpen | 0:9470a174c910 | 84 | for (int n=0; n<mySai.GetLength(); n++) |
MikamiUitOpen | 0:9470a174c910 | 85 | { |
MikamiUitOpen | 0:9470a174c910 | 86 | int16_t xL, xR; |
MikamiUitOpen | 0:9470a174c910 | 87 | mySai.Input(xL, xR); |
MikamiUitOpen | 0:9470a174c910 | 88 | sn[n] = (float)xL; |
MikamiUitOpen | 0:9470a174c910 | 89 | } |
mladjo1993 | 8:99d57d6e0ea1 | 90 | // Spectrum update |
mladjo1993 | 8:99d57d6e0ea1 | 91 | SpectrumUpdate(spectra, fftAnalyzer, sn, db); |
mladjo1993 | 8:99d57d6e0ea1 | 92 | // Display 2D spectrum |
mladjo1993 | 8:99d57d6e0ea1 | 93 | DisplaySpectrum2D(db, X0, Y0, W0_2D/H_BAR, H_BAR, lcd); |
mladjo1993 | 8:99d57d6e0ea1 | 94 | } |
mladjo1993 | 8:99d57d6e0ea1 | 95 | break; |
mladjo1993 | 8:99d57d6e0ea1 | 96 | case 1: |
mladjo1993 | 8:99d57d6e0ea1 | 97 | clearButton.Inactivate(); |
mladjo1993 | 8:99d57d6e0ea1 | 98 | if (screen == 0) |
mladjo1993 | 8:99d57d6e0ea1 | 99 | { |
mladjo1993 | 8:99d57d6e0ea1 | 100 | // Draw relationship between color and dB |
mladjo1993 | 8:99d57d6e0ea1 | 101 | DrawColorDb(Y0, AXIS_COLOR, lcd); |
mladjo1993 | 8:99d57d6e0ea1 | 102 | // Draw 3D axis |
mladjo1993 | 8:99d57d6e0ea1 | 103 | DrawAxis3D(X0, Y0, W0_3D, H0, AXIS_COLOR, MS100, PX_1KHZ, lcd); |
mladjo1993 | 8:99d57d6e0ea1 | 104 | // Screen - 3D |
mladjo1993 | 8:99d57d6e0ea1 | 105 | screen = 1; |
mladjo1993 | 8:99d57d6e0ea1 | 106 | } |
mladjo1993 | 8:99d57d6e0ea1 | 107 | if (mySai.IsCaptured()) |
mladjo1993 | 8:99d57d6e0ea1 | 108 | { |
mladjo1993 | 8:99d57d6e0ea1 | 109 | // Input of signal for one frame |
mladjo1993 | 8:99d57d6e0ea1 | 110 | for (int n=0; n<mySai.GetLength(); n++) |
mladjo1993 | 8:99d57d6e0ea1 | 111 | { |
mladjo1993 | 8:99d57d6e0ea1 | 112 | int16_t xL, xR; |
mladjo1993 | 8:99d57d6e0ea1 | 113 | mySai.Input(xL, xR); |
mladjo1993 | 8:99d57d6e0ea1 | 114 | sn[n] = (float)xL; |
mladjo1993 | 8:99d57d6e0ea1 | 115 | } |
mladjo1993 | 7:23b60827582d | 116 | // Spectrum update |
MikamiUitOpen | 0:9470a174c910 | 117 | SpectrumUpdate(spectra, fftAnalyzer, sn, db); |
mladjo1993 | 7:23b60827582d | 118 | // Display spectrum |
mladjo1993 | 8:99d57d6e0ea1 | 119 | DisplaySpectrum3D(spectra, X0, Y0, H_BAR, lcd); |
mladjo1993 | 8:99d57d6e0ea1 | 120 | } |
mladjo1993 | 8:99d57d6e0ea1 | 121 | break; |
mladjo1993 | 8:99d57d6e0ea1 | 122 | case 2: |
MikamiUitOpen | 6:b3885567877c | 123 | clearButton.Activate(); |
MikamiUitOpen | 6:b3885567877c | 124 | if (clearButton.Touched()) |
MikamiUitOpen | 0:9470a174c910 | 125 | { |
mladjo1993 | 8:99d57d6e0ea1 | 126 | if (screen == 1) |
mladjo1993 | 8:99d57d6e0ea1 | 127 | { |
mladjo1993 | 8:99d57d6e0ea1 | 128 | spectra.Fill(GuiBase::ENUM_BACK); // Process for clearing the spectrum display |
mladjo1993 | 8:99d57d6e0ea1 | 129 | DisplaySpectrum3D(spectra, X0, Y0, H_BAR, lcd); // Clear spectrum display |
mladjo1993 | 8:99d57d6e0ea1 | 130 | } |
mladjo1993 | 8:99d57d6e0ea1 | 131 | else |
mladjo1993 | 8:99d57d6e0ea1 | 132 | ClearDisplay(X0, Y0, W0_2D, H0+1, lcd); |
MikamiUitOpen | 6:b3885567877c | 133 | clearButton.Draw(); |
MikamiUitOpen | 0:9470a174c910 | 134 | } |
mladjo1993 | 8:99d57d6e0ea1 | 135 | break; |
MikamiUitOpen | 0:9470a174c910 | 136 | } |
MikamiUitOpen | 0:9470a174c910 | 137 | } |
MikamiUitOpen | 0:9470a174c910 | 138 | } |
MikamiUitOpen | 6:b3885567877c | 139 |